如何使用“normalizr”规范化这个简单的 API 响应?
Posted
技术标签:
【中文标题】如何使用“normalizr”规范化这个简单的 API 响应?【英文标题】:How to normalize this simple API response using "normalizr"? 【发布时间】: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”在屏幕截图的“类别”中。 【参考方案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 提供的“答案”在我得到的这种平面对象响应中更简单、更清晰。
干杯:)
【讨论】:
以上是关于如何使用“normalizr”规范化这个简单的 API 响应?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Jbuilder 和 Normalizr 之间展平数据
为啥我有这个 Uncaught TypeError: (0 , _normalizr.arrayOf) is not a function?