DEV Community

Cover image for How JS Symbols helps frontEnd developer to keep Metadata:
Aliakbar Salehi
Aliakbar Salehi

Posted on

How JS Symbols helps frontEnd developer to keep Metadata:

As a frontend Developer maybe you ask yourself what is the advantages of using Symbols? How it could help us to have cleaner and better code?
In this article we do not go in deep of the symbols specification, we try to use symbols In real app and see how it helps frontend world. if you search in google you will find a lot of resources about the symbols specification.

One of the common question which my friends always ask me on frontend developing is how to keep metadata related to the object which fetched fron the backend or rest api such as isLoading, is Edited, ... .

Imagin we want to show a book in a list with pagination from backend

    {
        "title":"Javascript",
        "author":{
            "name": "Aliakbar",
            "family":"Salehi"
        },
        "tags": ["javascript", "React", "frontend", "web"]
    }

and let user to select, edit or delete it.
In this situation we need metadata to keep the status of the book object

  • what is the index of the current book
  • is book data changed?
  • what is the current view of the book (edit, read, new, loding)
  • Errors on communication with data (update Error, delete error, ... )

theere are several data structure to keep these metadata:

  1. keep metadata seperated and connect to origin object via Identifier key:

        const book={
            "title":"Javascript",
            "author":{
                "name": "Aliakbar",
                "family":"Salehi"
            },
            "tags": ["javascript", "React", "frontend", "web"],
        }
    
        const metaData={
            isLoading:false,
            edited: false,
            mode: viewMode.Read
            index:12,
            totoalBooks: 128,
        }
    
  2. add metadata inside the original Object

        const book={
            "title":"Javascript",
            "author":{
                "name": "Aliakbar",
                "family":"Salehi"
            },
            "tags": ["javascript", "React", "frontend", "web"],
            __metadata:{
                isLoading:false,
                edited: false,
                mode: viewMode.Read
                index:12,
                totoalBooks: 128,
            }
    
        }
    

by default second approach is easier to read and access metadata specially when we work with a list of items, but it needs to sanitize the data and remove __metadata before sending the change into the backend as it is just client side metadata.

The magic of Symbol Properties:

I use always metadata inside the origin object as a Symbol property,

        const book={
            "title":"Javascript",
            "author":{
                "name": "Aliakbar",
                "family":"Salehi"
            },
            "tags": ["javascript", "React", "frontend", "web"],
            [Symbol.for("metadata")]:{
                isLoading:false,
                edited: false,
                viewMode: viewMode.Read
                index:12,
                totoalBooks: 128,
            }
        }

this approach has several advantage:

  • As you know, Symbol properties in Object acts as a private hidden property, so you can use JSON.stringify(book) without any concern about the metadata. read more

        /// update book after change
        restApi.Update(JSON.stringify(book))
        /// metadata property will be sanitized automatically without any effort or extra code
    
  • abother benifit of metadata as a symbol property is Symbols are not enumerable in for...in iterations.
    so you can iterate without any concern or extra logic/code in items ( it is to helpful when you use some libraries such as normalizr to normalize yorur data)

  • easy to access the metadata or change them

        book[Symbol.for("metadata")].isLoading = true;
        // or 
        const {mode , isLoading}= book[Symbol.for("metadata")]
        if(isLoading)
            renderBook( mode)
        else 
            renderLodingComponent()
    

Aliakbar Salehi

Top comments (0)