Author Archives: Mario

Json-api-normalizer: Why JSON API and Redux Work Best When Used Together

As a web developer, we have to manage the data needed for every application we work on. There are problems when doing so, such as:

  1. Fetch data from the back end.
  2. Store it somewhere locally in the front-end application.
  3. Retrieve the data from the local store and format it as needed by the specific view or screen.

In this article, we are going to discuss about the data usage from JSON, the JSON API and GraphQL back ends, and from that, we can learn the practical way on how to manage front-end application data. As for the real use, let’s imagine that we have carried out a survey that asks the same questions of many users. After each user has given their answers, other users can comment on them if wanted to. Our web app will perform a request to the back end, store the gathered data in the local store and render the content on the page. In order to make it stay simple, we will leave out the answer-creation flow.

Redux Best Practices

What makes Redux the best is that it is changeable no matter what kind of API you consume. It doesn’t matter whether you change your API from JSON to JSON API or even GraphQL and back during development, as long as you keep your data model, so it will not affect the implementation of your state management. Below is the explanation on the best practice using Redux:

  1. Keep Data Flat in the Redux Store

First, here’s the data model:

 

 

Based on the picture above, we have a question data object that might have many post objects. It is possible that each post might have many comment objects. Each post and comment has respectively one author.

Let’s say we have a back end that returns a specific JSON response. It is possible that it would have a carefully nested structure. If you store your data in the same way you do in the store, you will face many problems after that, like, for instance, you might store the same object many times like this:

{

  “text”: “My Post”,

  “author”: {

    “name”: “Yury”,

    “avatar”: “avatar1.png”

  },

  “comments”: [

    {

      “text”: “Awesome Comment”,

      “author”: {

            “name”: “Yury”,

        “avatar”: “avatar1.png”

      }

    }

  ]

}

In the example above, it indicates that we store the same Author object in several places, which is bad, because not only does it need more memory but it also has negative side effects. You would have to pass the whole state and update all instances of the same object especially if somebody changed the user’s avatar in the back end.

To prevent something like that from happening, we can store the data in a flattened structure. This way, each object would be stored only once and would be easily accessible.

{

  “post”: [{

    “id”: 1,

    “text”: “My Post”,

    “author”: { “id”: 1 },

    “comments”: [ { “id”: 1 } ]

  }],

  “comment”: [{

    “id”: 1,

    “text”: “Awesome Comment”

  }],

  “author”: [{

    “name”: “Yury”,

    “avatar”: “avatar1.png”,

    “id”: 1

  }]

 }

  1. Store Collections as Maps Whenever Possible

After we have the data in a good flat structure, we can gradually accumulate the received data, in order for us to reuse it as a cache, to improve performance or for offline use. However, if we combine new data in the existing storage, we have to select only relevant data objects for the specific view. We can store the structure of each JSON document separately to find out which data objects were provided in a specific request to gain this. There is a list of data object IDs that we can use to gather the data from the storage.

Let’s say there is a list of friends of two different users, Alice and Bob. We will then perform two requests to gather the list and review the contents of our storage consequently. Let’s suppose that from the start the storage is empty.

/ALICE/FRIENDS RESPONSE

Here’s the User data object with an ID of 1 and a name, Mike, like this:

{

  “data”: [{

    “type”: “User”,

    “id”: “1”,

    “attributes”: {

      “name”: “Mike”

    }

  }]

}

/BOB/FRIENDS RESPONSE

This is another request that would return a User with the ID of 2 and Kevin as the name:

{

  “data”: [{

    “type”: “User”,

    “id”: “2”,

    “attributes”: {

      “name”: “Kevin”

    }

  }]

}

STORAGE STATE

This is what our storage state would look like:

{

  “users”: [

    {

      “id”: “1”,

      “name”: “Mike”

    },

    {

        “id”: “2”,

        “name”: “Kevin”

    }

  ]

}

STORAGE STATE WITH META DATA

In order to find out or distinguish which data objects in storage are relevant, we have to keep the structure of the JSON API document. With that focus, we can change it into this:

{

  “users”: [

    {

      “id”: “1”,

      “name”: “Mike”

    },

    {

        “id”: “2”,

        “name”: “Kevin”

    }

  ],

  “meta”: {

      “/alice/friends”: [

        {

          “type”: “User”,

          “id”: “1”

        }

      ],

      “/bob/friends”: [

        {

          “type”: “User”,

          “id”: “2”

        }

      ]

  }

}

With this, we can now read the meta data and gather all mentioned data objects. Now here’s the recap of the operations’ complexities:

As can be seen from the picture above, maps certainly works better than arrays because all operations have O(1) as the complexity instead of O(n). If we use a map instead of an array for the User data object, it would be like this:

STORAGE STATE REVISED

{

  “users”: {

      “1”: {

        “name”: “Mike”

      },

      “2”: {

        “name”: “Kevin”

      }

  },

  “meta”: {

      “/alice/friends”: [

        {

          “type”: “User”,

          “id”: “1”

        }

      ],

      “/bob/friends”: [

        {

          “type”: “User”,

           “id”: “2”

        }

      ]

  }

}

Now with this simple method, we can find a specific user by ID almost instantly.

Processing the Data and JSON API

There are many solutions to convert JSON documents to a Redux-friendly form. However, while there is no significant change within the application’s lifecycle, it will cause a failure if things are too dynamic, even though normalizing the function with the provision of a JSON document works great if your data model is known in advance.

Using GraphQL might be possible and interesting as well; however, if our APIs are being consumed by many third parties, we can’t adopt it.

JSON API and Redux

Redux and the JSON API work best together. The data provided by the JSON API in a flat structure by definition conforms nicely with Redux best practices. The data is typified in order to be naturally saved in Redux’s storage in a map with the format type → map of objects.

There are things to consider, though. First, it should be noted that storing the types of data objects “data” and “included” as two separate entitles in the Redux store can violate Redux best practices, as the same data objects would be stored more than once.

To solve these problems, we can use the main features of json-api-normalizer, such as:

  • Merge data and included fields, normalizing the data.
  • Collections are converted into maps in a form of a id=> object.
  • The response’s original structure is stored in a special meta

First, in order to solve problems with redundant structures and circular dependencies, the introduction of the distinction of data and included data objects in the JSON API specification is needed. Second, there is a constant update on data in Redux, although gradually, that can help with the performance improvement.

 Now that you know why JSON API works best with Redux, it can be concluded that this approach can assist us in prototyping a lot faster and flexible with changes to the data model. If you are in doubt whether using Redux with JSON API or not, this article will help you find the solution and reason why you shouldn’t doubt this method.

Knowing Why Tabbed Content Might be Hurting Your Search Rankings

Every writer loves to see its website’s body content look clean and concise. Therefore, as a solution, they usually put content behind tabs, but is tabbed content a good thing for your search engine optimization? Every effort that you make should be relevant to Google, especially if you are writing for SEO service. Hence, in this article we are going to discuss about how tabbed content will hurt your search rankings and what you should do to fix it. Find the answers below.

Why Tabbed Content Can Hurt Your Rankings

It is no secret that search engine crawlers have a difficulty in reading JavaScript over the years. Even though Google has made so many attempts to understand how JavaScript has become essential in modern day website design, still, there are so many things that should be fixed. This is because JavaScript is a complicated yet beautiful thing.

However, since we don’t know what part of JavaScript that Google can and can’t read, the best solution we can offer is to make sure that your JS are readable and not disallowed in your robots.txt. When Google doesn’t understand, any piece of content within that sector won’t be displayed or rendered. This means your well-structured content will offer no value to your search aspirations.

To know whether Google can understand your content or not, you can use the Fetch as Google function within Google Search Console, which displays both a rendered version for Googlebot and how a visitor will see the page.

So, what’s wrong with tabbed content? Well, tabbed content is typically created using JavaScript using div.tabs. While search engine can typically read this, Google, on the other hand, doesn’t have the ability like a human has to click on a different tab. The main reason is because the action that displays the tabbed content isn’t a standard hyperlink that crawlers are designed to follow.

In the example below, you can see how a standard piece of tabbed content contains a standard hyperlink:

<button class=”tablinks” onclick=”OPENTAB(event, ‘EVENTNAME’)” id=”defaultOpen”>TAB TITLE</button>

<script>

document.getElementById(“defaultOpen”).click();

</script>

Therefore, Google can only read your first tab, since this is static on your page, while other tabs might be ignored. Can you imagine how many words you are losing out? For example, you have five tabs, all with 200 words in each, so you are losing out on 800 words on your page. In other words, this brings bad news to your webpage because it will surely lower your content quality for missing out on those keyword-rich and relevant pieces of content.

What Can We Do?

Nothing can make Googlebot effectively crawl your website, unless you completely remove tabbed content altogether. This is because tabbed content is dependent on the kind of code showcased above. By implementing this method, you can index every single piece of content you have created.

In fact, a research has been conducted to prove this theory. The results show that pages which weren’t gaining any positioning could possibly go from Page 3 to Page 1 only by removing the tabbed content. In fact, once the Googlebot notice that the rich content is not being hidden anymore, it will directly go to page 1 status.

Arguments against This Ideology

It is better to have many arguments rather than one, right? So, it will be good to consider other factors. Below is a short list of other possible factors that may have affected these search engine results:

  • Page age: When webpages have been developed for some times, it will get older, trust grows and will affect the position. However, the pages showcased in this research contain no information that indicates the date that the page is created.
  • Natural organic external links: In the time the research being monitored, no external links are built to these pages.
  • Algorithm changes: the ongoing content quality updates help. This means that ongoing algorithm changes would benefit pages that showcase more and relevant content.
  • Page creation: Prior to the page being developed, pages may not gain any position for 3 months.
  • Existing on-page optimization: Standard SEO is applied after the pages are created, such as meta optimization, content creation, header optimization and image optimization.

The Future Outlook

Now, the biggest question is, will Google ever be able to read tabbed content? There is no absolute answer for this question. In fact, any kind of answer is purely speculative. For now, through so many researches, we can conclude that Google isn’t ready to handle JavaScript, so it is better to keep a keen eye out for any JavaScript, for it may harm your websites rank.