Recently I have just added the possibility to share your code snippets with the world on Bookmarks.dev. I have noticed that the code to create and update code snippets, was too intertwined - trying to avoid code duplication I used initially just one component to create and update code snippets. Now, I just could not stand the too many conditional checks anymore, so I decided to split the functionality in two parts

  • one for handling updating and copy to mine, and the second for creating new snippets.

Because there is still some common functionality in both, like handling autocompletion of tags, I decided to use Angular component inheritance to avoid code duplication. In this blog post I will just show code examples for inheritance and name the angular inheritance particularities.

Octocat Source code for bookmarks.dev is available on Github - Star

Continue Reading ...

The @XmlAccessorType(XmlAccessType.FIELD) is required if you set @XmlElement annotations on the fields instead of the getters methods

package dev.bookmarks.example;

import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "bookmarks")
public class BookmarksResponse {

  @XmlElement(name = "bookmark", type = BookmarkDto.class)
  private List<BookmarkDto> bookmarks;

  public BookmarksResponse () {
  }

  public BookmarksResponse (List bookmarks) {
    this.bookmarks= bookmarks;
  }

  public List<BookmarkDto> getAllBookmarks() {
    return bookmarks;
  }

  public void setBookmarks(
      List<Bookmark> bookmarks) {
    this.bookmarks= bookmarks;
  }
}

The BookmarkDto class (getters and setters not shown for brevity):

package dev.bookmarks.example;

import com.fasterxml.jackson.annotation.JsonProperty;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.EqualsAndHashCode;
import lombok.ToString;

@EqualsAndHashCode
@ToString
@XmlRootElement(name = "bookmark")
@XmlAccessorType(XmlAccessType.FIELD)
public class BookmarkDto {

  @JsonProperty("id")
  @XmlAttribute(name = "id")
  Integer id;

  @JsonProperty("name")
  @XmlAttribute(name = "name")
  String name;

  @JsonProperty("url")
  @XmlAttribute(name = "url")
  String url;

  public BookmarkDto() {
  }

 //getters and setters hidden for brevity
}


Would result in an xml response if you request with the Accept header as Accept: application/xml as the following

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookmarks>
    <boomark id="1">
      <name>How to filter results list in Angular with input text</name>
      <url>https://www.codepedia.org/ama/how-to-filter-results-in-angular-example-with-input-text</url>
   </bookmark>
    <boomark id="2">
      <name>Complete example of a CRUD API with Express GraphQL</name>
      <url>https://www.codepedia.org/ama/complete-example-crud-api-express-graphql</url>
   </bookmark>
</bookmarks

The Accept: application/json response should look like the following

{
    "bookmarks": [
        {
            "id": 1,
            "name": "How to filter results list in Angular with input text",
            "url": "https://www.codepedia.org/ama/how-to-filter-results-in-angular-example-with-input-text"
        },
        {
            "id": 2,
            "name": "Complete example of a CRUD API with Express GraphQL",
            "url": "https://www.codepedia.org/ama/complete-example-crud-api-express-graphql"
        }
   ]
}

Shared with from Bookmarks.dev. Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Use a global replace with \W+ option ( \W+ means any sequence of non-word characters)


    private generateDashBasedUrlPathFromTitle(title: string) {
        return title.trim().replace(/\W+/g, '-').toLowerCase();
    }

Shared with from Bookmarks.dev. Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Select one parameter

router.get('/:userId/profile', async (request, response) => {
  const userId = request.params.userId;
 // ....
});

Select multiple path parameters

personalBookmarksRouter.get('/:bookmarkId', keycloak.protect(), async (request, response) => {
  const {userId, bookmarkId} = request.params;
  // ...
});

Reference - https://github.com/BookmarksDev/bookmarks.dev


Shared with from Bookmarks.dev. Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Use the arr.join([separator]) function. The separator specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (“,”). If separator is an empty string, all elements are joined without any characters in between them.

    private generateBlogPostHeader(commaSeparatedListOfTags: string, snippet: Snippet): string {
        let header: string = '';

        header += 'categories: [snippets]\n';
        header += `tags: [${snippet.tags.join(',')}]\n`;
        header += '---\n';

        return header;
    }

You can also use the toString() method in this particular case with the same result

header += `tags: [${snippet.tags.toString()}]\n`;

Reference - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join


Shared with from Bookmarks.dev. Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.