How to normalize the data from the JSON with normalizr?

640 Views Asked by At

I am quite new to the normalizr and can't understand it well enough yet. How can I normalize the following JSON response so it can be used for the Redux:

{
    "statusCode":200,
    "message":"Random quotes",
    "pagination":{
          "currentPage":1,
          "nextPage":null,
          "totalPages":1
        },
    "totalQuotes":1,
    "data":[
        {
          "_id":"5eb17aadb69dc744b4e70e05",
          "quoteText":"One crowded hour of glorious life is worth an age without a name.",  
          "quoteAuthor":"Walter Scott",
          "quoteGenre":"age",
          "__v":0
        }
    ]
}

It would be useful to put the data object at the top level in the normalized object. How can I combine this with TypeScript? Thank you in advance.

1

There are 1 best solutions below

0
Linda Paiste On

Typescript types can definitely help you to understand the data that you are dealing with. You want to describe various pieces of the response with their own types and then piece them together.

interface Quote {
  _id: string;
  quoteText: string;
  quoteAuthor: string;
  quoteGenre: string;
  __v: number;
}

interface Pagination {
  currentPage: number;
  nextPage: null | number; // what is this when it's not null?
  totalPages: number;
}

interface APIResponse {
  statusCode: number;
  message: string;
  pagination: Pagination;
  totalQuotes: number;
  data: Quote[];
}

normalizr isn't super helpful here because you only have one entity type which is a Quote. In a sense you have two entity types if you are treating the response itself as an entity. But I'm not sure how you would extract a unique id from it. You'd probably have to add it yourself based on the API path/params since that information is lacking in the JSON.

const quote = new schema.Entity("quote", {}, { idAttribute: "_id" });

const response = new schema.Entity("response", {
  data: [quote] // an array of quote entities
});

console.log(normalize({...json, id: "/random-quote"}, response));

This gives you

{
  "entities": {
    "quote": {
      "5eb17aadb69dc744b4e70e05": {
        "_id": "5eb17aadb69dc744b4e70e05",
        "quoteText": "One crowded hour of glorious life is worth an age without a name.",
        "quoteAuthor": "Walter Scott",
        "quoteGenre": "age",
        "__v": 0
      }
    },
    "response": {
      "/random-quote": {
        "statusCode": 200,
        "message": "Random quotes",
        "pagination": {
           "currentPage": 1,
           "nextPage": null,
           "totalPages": 1
        },
        "totalQuotes": 1,
        "data": ["5eb17aadb69dc744b4e70e05"],
        "id": "/random-quote"
      }
    }
  },
  "result": "/random-quote"
}