Разрешить в 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);
  }
}
Другие вопросы по тегам