使用 Observables 保持对 JSON-API 的嵌套 http 调用之间的关系
Keep relation between nested http calls to JSON-API with Observables
问题: 我在 Angular 2 项目中使用 RXJS。我从 JSON-API 获取数据。 API 提供研究和问卷调查。在我们的模型中,一项研究可以 "contain" 一份或多份问卷。研究有 ID,问卷有 ID。我想列出所有问卷及其相关研究的 ID,但我丢失了研究 ID 和问卷对象之间的 "link"。
示例:假设问卷 ID 4、5、6 与研究 ID 1 相关联,问卷 ID 7、8 与研究 ID 2 相关联。
研究看起来像这样(GET:.../api/v1/studies/1
):
{type: "study", id: "1", attributes: Object}
{type: "study", id: "2", attributes: Object}
问卷看起来像这样(例如:GET:.../api/v1/questionnaires/4
):
{type: "questionnaires", id: "4", attributes: Object}
{type: "questionnaires", id: "5", attributes: Object}
{type: "questionnaires", id: "6", attributes: Object}
{type: "questionnaires", id: "7", attributes: Object}
{type: "questionnaires", id: "8", attributes: Object}
我想在一个列表中显示所有问卷,并且对于每份问卷并显示它关联的研究 ID,例如:
{type: "questionnaires", id: "4", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "5", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "6", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "7", attributes: Object, associatedStudyId: "2"}
{type: "questionnaires", id: "8", attributes: Object, associatedStudyId: "2"}
对 .../api/v1/studies/1/questionnaires
的 GET 调用 returns:
[{"type": "questionnaires", "id": "4"},{"type": "questionnaires","id": "5"}]
代码: 我已经知道了我需要的所有组件,我只是不知道如何将研究 ID 附加到相应的问卷对象.
getQuestionnaires(studyIds) {
console.log(studyIds); // see output [1]
this.editableQuestionnaires = [];
let studyIdsObs = Rx.Observable.from(studyIds);
let questShortStream = studyIdsObs.flatMap((id) => {
return this.apiService.getQuestionnairesOfStudy(id)
});
questShortStream.subscribe(console.log);
let questsAndStudyId = Rx.Observable.zip(studyIdsObs, questShortStream,
(id, quests) => {
return {
studyId: id,
questionnaires: quests
}
})
questsAndStudyId.subscribe(console.log) // see output [2]
let studyIdAndQuestIds = questsAndStudyId.map((obj) => {
let questIds = [];
for (let i = 0; i < obj.questionnaires.length; i++) {
questIds.push(obj.questionnaires[i].id);
}
return {
studyId: obj.studyId,
questionnaireIds: questIds
}
});
studyIdAndQuestIds.subscribe(console.log); // see output [3]
let questionnaireIdsObs = studyIdAndQuestIds.flatMap(obj => {
return Rx.Observable.from(obj.questionnaireIds);
})
questionnaireIdsObs.subscribe(console.log) // see output[4]
let questionnairesObs = questionnaireIdsObs.flatMap(id => this.apiService.getEditableQuestionnaire(id))
questionnairesObs.subscribe(console.log) // see output [5]
}
输出:
[1]
[ "1", "2", "3" ]
[2]
[ Object, Object ]
[ Object, Object, Object ]
[3]
Object { studyId: "1", questionnaires: Array[3] }
Object { studyId: "2", questionnaires: Array[2] }
[4]
4
5
6
7
8
[5]
Object { type: "questionnaires", id: "4", attributes: Object}
Object { type: "questionnaires", id: "5", attributes: Object}
Object { type: "questionnaires", id: "6", attributes: Object}
Object { type: "questionnaires", id: "7", attributes: Object}
Object { type: "questionnaires", id: "8", attributes: Object}
你能做点像...
studyIds.forkJoin(
studyIds.map(studyId =>
service.getQuestionaires(studyId).map(questionaires =>
questionaires.map(questionaire => {
questionaire.associatedStudyId = studyId;
return questionaire;
})
)
)
);
问题: 我在 Angular 2 项目中使用 RXJS。我从 JSON-API 获取数据。 API 提供研究和问卷调查。在我们的模型中,一项研究可以 "contain" 一份或多份问卷。研究有 ID,问卷有 ID。我想列出所有问卷及其相关研究的 ID,但我丢失了研究 ID 和问卷对象之间的 "link"。
示例:假设问卷 ID 4、5、6 与研究 ID 1 相关联,问卷 ID 7、8 与研究 ID 2 相关联。
研究看起来像这样(GET:.../api/v1/studies/1
):
{type: "study", id: "1", attributes: Object}
{type: "study", id: "2", attributes: Object}
问卷看起来像这样(例如:GET:.../api/v1/questionnaires/4
):
{type: "questionnaires", id: "4", attributes: Object}
{type: "questionnaires", id: "5", attributes: Object}
{type: "questionnaires", id: "6", attributes: Object}
{type: "questionnaires", id: "7", attributes: Object}
{type: "questionnaires", id: "8", attributes: Object}
我想在一个列表中显示所有问卷,并且对于每份问卷并显示它关联的研究 ID,例如:
{type: "questionnaires", id: "4", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "5", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "6", attributes: Object, associatedStudyId: "1"}
{type: "questionnaires", id: "7", attributes: Object, associatedStudyId: "2"}
{type: "questionnaires", id: "8", attributes: Object, associatedStudyId: "2"}
对 .../api/v1/studies/1/questionnaires
的 GET 调用 returns:
[{"type": "questionnaires", "id": "4"},{"type": "questionnaires","id": "5"}]
代码: 我已经知道了我需要的所有组件,我只是不知道如何将研究 ID 附加到相应的问卷对象.
getQuestionnaires(studyIds) {
console.log(studyIds); // see output [1]
this.editableQuestionnaires = [];
let studyIdsObs = Rx.Observable.from(studyIds);
let questShortStream = studyIdsObs.flatMap((id) => {
return this.apiService.getQuestionnairesOfStudy(id)
});
questShortStream.subscribe(console.log);
let questsAndStudyId = Rx.Observable.zip(studyIdsObs, questShortStream,
(id, quests) => {
return {
studyId: id,
questionnaires: quests
}
})
questsAndStudyId.subscribe(console.log) // see output [2]
let studyIdAndQuestIds = questsAndStudyId.map((obj) => {
let questIds = [];
for (let i = 0; i < obj.questionnaires.length; i++) {
questIds.push(obj.questionnaires[i].id);
}
return {
studyId: obj.studyId,
questionnaireIds: questIds
}
});
studyIdAndQuestIds.subscribe(console.log); // see output [3]
let questionnaireIdsObs = studyIdAndQuestIds.flatMap(obj => {
return Rx.Observable.from(obj.questionnaireIds);
})
questionnaireIdsObs.subscribe(console.log) // see output[4]
let questionnairesObs = questionnaireIdsObs.flatMap(id => this.apiService.getEditableQuestionnaire(id))
questionnairesObs.subscribe(console.log) // see output [5]
}
输出:
[1]
[ "1", "2", "3" ]
[2]
[ Object, Object ]
[ Object, Object, Object ]
[3]
Object { studyId: "1", questionnaires: Array[3] }
Object { studyId: "2", questionnaires: Array[2] }
[4]
4
5
6
7
8
[5]
Object { type: "questionnaires", id: "4", attributes: Object}
Object { type: "questionnaires", id: "5", attributes: Object}
Object { type: "questionnaires", id: "6", attributes: Object}
Object { type: "questionnaires", id: "7", attributes: Object}
Object { type: "questionnaires", id: "8", attributes: Object}
你能做点像...
studyIds.forkJoin(
studyIds.map(studyId =>
service.getQuestionaires(studyId).map(questionaires =>
questionaires.map(questionaire => {
questionaire.associatedStudyId = studyId;
return questionaire;
})
)
)
);