Search code examples
reactjsreduxnormalizr

How to normalize this simple API response using "normalizr"?


I have this response coming from an API ...

{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "category_id": 1,
            "creator_id": 1,
            "instructor_id": 1,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "hebae",
            "overview": "Course Overview",
            "deleted_at": null,
            "created_at": "2020-01-02 15:16:08",
            "updated_at": "2020-01-02 15:16:08"
        },
        {
            "id": 2,
            "category_id": 1,
            "creator_id": 1,
            "instructor_id": 2,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "update course 1",
            "overview": "Course Overview",
            "deleted_at": null,
            "created_at": "2020-01-02 15:18:40",
            "updated_at": "2020-01-02 15:19:06"
        },
        {
            "id": 3,
            "category_id": 1,
            "creator_id": 1,
            "instructor_id": 1,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "hebaTest",
            "overview": "Course Overview",
            "deleted_at": null,
            "created_at": "2020-01-02 15:24:09",
            "updated_at": "2020-01-02 15:24:09"
        },
        {
            "id": 4,
            "category_id": 2,
            "creator_id": 1,
            "instructor_id": 1,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "hebaTest",
            "overview": "Adile",
            "deleted_at": null,
            "created_at": "2020-01-02 15:25:03",
            "updated_at": "2020-01-02 15:25:03"
        },
        {
            "id": 5,
            "category_id": 2,
            "creator_id": 1,
            "instructor_id": 1,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "hebaTest",
            "overview": "Adile",
            "deleted_at": null,
            "created_at": "2020-01-02 15:33:06",
            "updated_at": "2020-01-02 15:33:06"
        },
        {
            "id": 6,
            "category_id": 1,
            "creator_id": 1,
            "instructor_id": 1,
            "difficulty_id": 1,
            "status_id": 1,
            "title": "Course Title",
            "overview": "Course Overview",
            "deleted_at": null,
            "created_at": "2020-01-05 08:24:56",
            "updated_at": "2020-01-05 08:24:56"
        },
    ],
    "first_page_url": "http://skillboardbackend-staging.zph2jwe3pc.eu-west-1.elasticbeanstalk.com/api/course?page=1",
    "from": 1,
    "last_page": 2,
    "last_page_url": "http://skillboardbackend-staging.zph2jwe3pc.eu-west-1.elasticbeanstalk.com/api/course?page=2",
    "next_page_url": "http://skillboardbackend-staging.zph2jwe3pc.eu-west-1.elasticbeanstalk.com/api/course?page=2",
    "path": "http://skillboardbackend-staging.zph2jwe3pc.eu-west-1.elasticbeanstalk.com/api/course",
    "per_page": 15,
    "prev_page_url": null,
    "to": 15,
    "total": 29
}

I'm trying to get the "data" array to be defined as "categories" object, and the rest data can stay the same, how to do that with normalizr?

I tried this ...

const { data } = await apiGetAllCategories();

const dataSchema = new schema.Entity("categories");
const coursesSchema = new schema.Entity("info", {
    data: [dataSchema]
});
const normalizedData = normalize(data, coursesSchema);
console.log(normalizedData);

But it always gives me the "info" as undefined, and the "result" as undefined ...

enter image description here

What am I doing wrong here?


Solution

  • For anyone interested in how to normalize this response with "normalizr", I figured out where I went wrong, and that normalizr usually looks for and an "id" key at the top level, and if it can't find that you gonna have to provide it, in my case there was no "id" on the top-level object, so I gave it the "per_page" as an id to make it work ...

    const dataSchema = new schema.Entity("data");
    const coursesSchema = new schema.Entity( "info", 
    { 
        data: [dataSchema]
    }, { idAttribute: "per_page" } );
    
    const normalizedData = normalize(data, coursesSchema);
    

    By the way the "answer" provided by @Drew Reese is way simpler and cleaner in this kind of flat object response that I got.

    Cheers :)