#javascript #angular #rxjs
#javascript #угловой #rxjs
Вопрос:
У меня есть служба с 3 общедоступными методами. Они зависят от результата this.dossierService.dossierIds
. dossierIds
является получателем, который возвращает BehaviorSubject<DossierIds[]>
.
public createObligation(id: string): Observable<void> {
return this.getObligationsUrl(id).pipe(
map(dossierIds => {
const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla}`;
return this.http.post(endpoint);
})
);
}
public deleteMortgageObligation(id: string): Observable<void> {
return this.getObligationsUrl(id).pipe(
map(dossierIds => {
const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
return this.http.delete(endpoint);
})
);
}
public updateObligation(id: string): Observable<void> {
//..
}
private getObligationsUrl(dossierIds: DossierIds): string {
return this.dossierService.dossierIds.pipe(
map(dossierIds => {
const dossierId = dossierIds.getDossierId();
const moId = dossierIds.getObligationsId();
return `${BASE_URL}/${dossierId}/${OBLIGATIONS_URL}/${moId}`;
}),
);
}
Эти методы будут использоваться в компоненте, подобном этому
this.createObligation(123).subscribe(result => {
console.log(result);
})
Но TypeScript выдает мне ошибку во всех 3 методах, говоря:
Type 'Observable<Observable<void>>' is not assignable to type 'Observable<void>'. Type 'Observable<void>' is not assignable to type 'void'.
И я даже не вижу, что мои HTTP-запросы запускаются. Где я допустил ошибку?
Ответ №1:
Причина, по которой http-вызов не выполняется, заключается в том, что вы не подписываетесь на внутренний наблюдаемый.
1 public deleteMortgageObligation(id: string): Observable<void> {
2 return this.getObligationsUrl(id).pipe(
3 map(dossierIds => {
4 const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
5 return this.http.delete(endpoint);
6 })
7 );
8 }
В строке # 5 вы возвращаете observable, но на него никогда не подписывается. Таким образом, возвращается строка # 2 Observable<Observable<>>
. Вам необходимо убедиться, что на этот внутренний наблюдаемый подписан и что его результат передается через поток.
Это именно то, для чего предназначены «Операторы сопоставления более высокого порядка«. Они выполняют следующее:
- сопоставляет входящее значение с другим наблюдаемым
- подписывается на него, поэтому его значения передаются в поток
- управляет отменой подписки на эти «внутренние подписки»
В вашем случае мы можем просто использовать switchMap
on line # 3 вместо map
:
1 public deleteMortgageObligation(id: string): Observable<void> {
2 return this.getObligationsUrl(id).pipe(
3 switchMap(dossierIds => {
4 const endpoint = `${this.getObligationsUrl(dossierIds)}/blablabla/${id}`;
5 return this.http.delete(endpoint);
6 })
7 );
8 }