如何使用 "normalizr" 规范化这个简单的 API 响应?

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

我的回复来自 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
}

我正在尝试将 "data" 数组定义为 "categories" 对象,其余数据可以保持不变,如何使用 normalizr 做到这一点?

我试过了...

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);

但它总是给我未定义的 "info",以及未定义的 "result" ...

我做错了什么?

您的数据似乎已经是某种 reduced/normalized 形式,因为我没有看到任何嵌套或重复的数据结构。我认为对您的数据进行简单的 array::reduce 就足以满足您的需求。

// Reduce data array to map [element.id => element]
const dataObject = data.reduce((dataObject, item) => {
  dataObject[item.id] = item;
  return dataObject;
}, {});

const 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"
  }
];

// Reduce data array to map [element.id => element]
const dataObject = data.reduce((dataObject, item) => {
  dataObject[item.id] = item;
  return dataObject;
}, {});

console.log(dataObject);

对于任何对如何使用 "normalizr" 规范化此响应感兴趣的人,我想出了我哪里出错了,normalizr 通常会在顶部查找 "id" 键级别,如果它找不到你必须提供它,在我的例子中,顶级对象上没有 "id",所以我给它 "per_page" 作为 id 来制作它有效...

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

const normalizedData = normalize(data, coursesSchema);

顺便说一下,@Drew Reese 提供的 "answer" 在我得到的这种平面对象响应中更加简单和清晰。

干杯 :)