【问题标题】:How to normalize this simple API response using "normalizr"?如何使用“normalizr”规范化这个简单的 API 响应?
【发布时间】:2020-04-24 08:41:17
【问题描述】:

我有这个来自 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
}

我正在尝试将“数据”数组定义为“类别”对象,其余数据可以保持不变,如何使用 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);

但它总是给我未定义的“信息”,而未定义的“结果”...

我在这里做错了什么?

【问题讨论】:

  • 以上 API 响应似乎没有那么深的嵌套,它需要额外的库来提取任何数据。向我们展示所需的输出数据样本,我很确定有一个简单的 vanilla js 解决方案可供建议。
  • @YevgenGorbunkov 我只需要与响应相同的结构,除了数据是对象而不是数组,并且该对象的键是 id,就像我从“ normalizr”在屏幕截图的“类别”中。

标签: reactjs redux normalizr


【解决方案1】:

您的数据似乎已经是某种简化/规范化的形式,因为我没有看到任何嵌套或重复的数据结构。我认为对您的数据使用简单的 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”,如果它找不到你就必须提供它,这就是我所做的...
  • ` const dataSchema = new schema.Entity("data"); const courseSchema = new schema.Entity("info", { data: [dataSchema] }, { idAttribute: "per_page" }); const normalizedData = normalize(数据,课程架构); `
  • 我会接受你的回答,因为这对我来说似乎是合乎逻辑的,但正如我所说,我试图找出我做错了什么。非常感谢:)
  • @Ruby 您可以回答自己的问题,我认为您应该这样做,因为从技术上讲,这将是对原始问题的 正确 答案,而不仅仅是替代解决方案“有效”。
【解决方案2】:

对于任何对如何使用“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 提供的“答案”在我得到的这种平面对象响应中更简单、更清晰。

干杯:)

【讨论】:

    猜你喜欢
    • 2016-06-10
    • 2017-06-23
    • 2016-06-21
    • 2019-03-24
    • 2018-10-19
    • 2021-08-13
    • 2021-04-14
    • 2018-04-09
    • 2018-03-05
    相关资源
    最近更新 更多