Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Foreach内部调用Subscribe_Javascript_Angular_Foreach_Rxjs_Subscribe - Fatal编程技术网

Javascript 在Foreach内部调用Subscribe

Javascript 在Foreach内部调用Subscribe,javascript,angular,foreach,rxjs,subscribe,Javascript,Angular,Foreach,Rxjs,Subscribe,我有一个包含问题列表的调查,每个问题都包含多项选择答案列表。我试图把这个推到我的后端,但根据我的数据库,它只推了调查的第一个问题。我确保问题和答案正确插入,并使用Graphql测试了突变 this._surveyService.addSurveyToInitiative(this._initiativeId, this.name, this.category, "TBD").subscribe(surveyData => { this.survey.quest

我有一个包含问题列表的调查,每个问题都包含多项选择答案列表。我试图把这个推到我的后端,但根据我的数据库,它只推了调查的第一个问题。我确保问题和答案正确插入,并使用Graphql测试了突变

this._surveyService.addSurveyToInitiative(this._initiativeId, this.name, this.category, "TBD").subscribe(surveyData => {
     this.survey.questions.forEach(question => {
        this._surveyService.addQuestionToSurvey(surveyData.data.createSurvey.survey.id, question.question).subscribe(questionData=> {
          question.multipleChoiceAnswers.forEach(answer => {
            this._surveyService.addMultipleChoiceAnswerToQuestion(questionData.data.addQuestionToSurvey.newQuestion.id, answer).subscribe()
          })
        })
     })
   })
}

你不应该连锁订阅。forEach也是一个最终操作,这意味着它不会返回任何内容。你应该改用

更好的方法是使用以下方法:

this._surveyService.addSurveyToInitiative(this._initiativeId, this.name, this.category, "TBD")
    .pipe(
        map(surveyData => surveyData.data.createSurvey.survey.id),
        mergeMap(surveyId => this.survey.questions.map(question => this._surveyService.addQuestionToSurvey(surveyId, question.question))),
        map(questionData => questionData.data.addQuestionToSurvey.newQuestion.id),
        mergeMap(questionId => question.multipleChoiceAnswers.forEach(answer => this._surveyService.addMultipleChoiceAnswerToQuestion(questionId, answer)))
    ).subscribe();

乍一看,问题似乎不是RxJS或
subscribe
。你的服务电话可能是罪魁祸首。也就是说,很难调试

在循环中嵌套
subscribe
和/或调用
subscribe
基本上总是一种反模式。您正在肆意地混合命令式和函数式编程风格——这并不是说您不能让它工作,而是挑逗出哪里出了问题(更不用说在将来维护/扩展它)变得更具挑战性

首先,让我们从更具功能性的角度重写:

this.\u surveyService.addSurveyToInitiative(
这个,
这个名字,
这一类,,
“待定”
).烟斗(
地图(测量数据=>
this.survey.question.map(问题=>
此.\u surveyService.addQuestionToSurvey(
surveyData.data.createSurvey.survey.id,
问题
).烟斗(
映射(questionData=>({question,questionData}))
)
)
),
合并映射(serviceCalls=>merge(…serviceCalls)),
map({question,questionData})=>
问题.multipleChoiceAnswers.map(答案=>
此.\u surveyService.add多回音回答问题(
questionData.data.addQuestionToSurvey.newQuestion.id,
回答
)
)
),
合并映射(serviceCalls=>merge(…serviceCalls))
).subscribe();
这里,这一行:
mergeMap(serviceCalls=>merge(…serviceCalls))
(见两遍)实际上是您订阅所有呼叫的方式

这应该更容易调试。现在,您可以
点击流的任何部分,查看此时发生的情况

this.\u surveyService.addSurveyToInitiative(
这个,
这个名字,
这一类,,
“待定”
).烟斗(
轻触(surveyData=>console.log(“处理surveyData:,surveyData)),
地图(测量数据=>
this.survey.question.map(问题=>
此.\u surveyService.addQuestionToSurvey(
surveyData.data.createSurvey.survey.id,
问题
).烟斗(
映射(questionData=>({question,questionData}))
)
)
),
合并映射(serviceCalls=>merge(…serviceCalls)),
点击(questionAndData=>console.log(“处理questionAndData:”,questionAndData)),
map({question,questionData})=>
问题.multipleChoiceAnswers.map(答案=>
此.\u surveyService.add多回音回答问题(
questionData.data.addQuestionToSurvey.newQuestion.id,
回答
)
)
),
合并映射(serviceCalls=>merge(…serviceCalls))
).subscribe(x=>console.log(“完成处理最后一步,得到响应:”,x));
现在,您可以
延迟
某些调用,或者使用
concat(…
而不是
merge(…
)来了解流在做什么

旁白: 这里是同样的事情,只是更简洁一点(我们结合合并调用):

this.\u surveyService.addSurveyToInitiative(
这个,
这个名字,
这一类,,
“待定”
).烟斗(
合并地图(调查数据=>
合并(…this.survey.question.map(问题=>
此.\u surveyService.addQuestionToSurvey(
surveyData.data.createSurvey.survey.id,
问题
).烟斗(
映射(questionData=>({question,questionData}))
)
))
),
合并地图({question,questionData})=>
合并(…question.multipleChoiceAnswers.map(答案=>
此.\u surveyService.add多回音回答问题(
questionData.data.addQuestionToSurvey.newQuestion.id,
回答
)
))
)
).subscribe();
更新#1 你确定吗

this.survey.question.map(question =>
是吗?似乎是一个奇怪的命名惯例。我希望有更类似的东西

this.survey.questions.map(question =>

首先感谢您的帮助!我尝试运行您的代码,从语法上看它可以正常工作,但在后端它与我的代码的工作方式相同。因此它将第一个问题推送到调查中,而没有任何答案。(this.survey.questions是正确的,因为调查中有一个问题列表)。再次感谢。我的回答的一部分是为了帮助您调试。在您的问题中,您出现的问题并不明显/可见。您必须更新您的问题,然后才能希望获得进一步的帮助。