Разрешить в Angular для нескольких вызовов API
Я пытаюсь вызвать 3 разных API, прежде чем компонент загружается с помощью Resolve.
Этот код ниже написан внутри функции разрешения и возвращает объект со всеми упакованными ответами.
Теперь, когда компонент загружается, прежде чем я получу ответ от сервера.. он возвращает ноль для каждого из ключей в возвращаемом объекте.
Пожалуйста, помогите, как я могу решить эту проблему. Как мне остановить его возврат до тех пор, пока ответ не получен от API.
resolve() {
this._apiFactory.getA().subscribe(response => {
responseA = response;
});
this._apiFactory.getB().subscribe( response => {
responseB = response;
});
this._apiFactory.getC().subscribe( response => {
responseC = response;
});
return {
'A': responseA ,
'B': responseb ,
'C': responseC
};
}
1 ответ
Вы возвращали до того, как ваши подписки могли быть закончены. Используется Fork Join, чтобы ждать, пока все ваши Get
запросы завершаются, а затем возвращаются результаты запросов get в требуемом формате.
resolve() {
let join = Observable.forkJoin(
this._apiFactory.getA().map(),
this._apiFactory.getB().map(),
this._apiFactory.getC().map()
)
return join.map(
([responseA, responseB, responseC]) => {
return {
'A': responseA ,
'B': responseb ,
'C': responseC
}
}
).first()
}
РЕДАКТИРОВАТЬ: Я попробовал это в Angular 6
и я смог сделать это так:
// dummy Observables
let a = of([1]).pipe(delay(1000));
let b = of([1, 2, 3]).pipe(delay(2000));
let c = of([1, 2, 3, 4]).pipe(delay(3000));
let join = forkJoin(a,b,c).pipe(map((allResponses) => {
return {
A: allResponses[0],
B: allResponses[1],
C: allResponses[2]
};
}));
return join;
Итак, я манипулировал данными в forkJoin
и вернул forkJoin
сам. посмотреть его здесь: https://stackblitz.com/edit/angular-xepafp?file=src%2Fapp%2FAPIResolver.ts
В angular2 что-то вроде этого должно работать (также попробуйте удалить map
от Observables
под forkJoin
и посмотреть..):
resolve() {
return Observable.forkJoin(
this._apiFactory.getA().map(),
this._apiFactory.getB().map(),
this._apiFactory.getC().map()
).map((allResponses) => {
return {
A: allResponses[0],
B: allResponses[1],
C: allResponses[2]
};
})
}
Начиная с RxJS 6.5+, способ сделать это:
return forkJoin({
todos: timer(500).pipe(mapTo([{ title: 'forkJoin'}])),
user: timer(500).pipe(mapTo({ id: 1 }))
});
Пожалуйста, не используйте подписку, вместо этого вы можете вернуть свои наблюдаемые как
let a= observable(1);
let b= observable(2);
let c= observable(3);
return forkJoin(a,b,c);
это поможет тебе
Это можно сделать с помощью combineLatest
также. Посмотреть этот stackblitz
import { Injectable } from "@angular/core";
import { Resolve, ActivatedRouteSnapshot } from "@angular/router";
import { of, combineLatest } from "rxjs";
import { delay } from "rxjs/operators";
@Injectable({
providedIn: "root"
})
export class TestResolver implements Resolve<any> {
constructor() {}
resolve(route: ActivatedRouteSnapshot) {
let a = of([1]).pipe(delay(1000));
let b = of([1, 2, 3]).pipe(delay(2000));
let c = of([1, 2, 3, 4]).pipe(delay(3000));
return combineLatest(a, b, c);
}
}