Necesitamos llamar a varias API REST desde ngOnInit() una por una. Después de llamar a la primera, necesitamos pasar esta respuesta en la segunda llamada a la API y lo mismo para la tercera, necesitamos obtener el valor de la segunda llamada a la API y pasarla a la tercera.
Pero mientras llamamos como a continuación, siempre obtenemos un valor indefinido.
this.globalVar1 : any; this.globalVar2 : any; this.globalVar3 : any; async ngOnInit() { this.apiService.getFirstAPICall(request).subscribe(info => { this.globalVar1 = info; //here value is coming from API service call } console.log(this.globalVar1); //here undefined //Now calling the second API ** here we need this first variable //but due to undefined we are getting error this.apiService.getSecondAPICall(request.globalVar1).subscribe(info => { this.globalVar2 = info; } console.log(this.globalVar2); //here undefined
Está ejecutando código asincrónico, lo que significa que sus solicitudes se pueden ejecutar en paralelo, luego sucede que realiza la segunda solicitud antes de que los resultados de la primera estén aquí.
Hay varias formas de hacer que su código se ejecute secuencialmente, una sería usar la palabra clave await
. Esto espera a que termine el código en la línea actual antes de ejecutar la siguiente línea.
Su código entonces se vería así:
this.globalVar1 : any; this.globalVar2 : any; this.globalVar3 : any; async ngOnInit() { this.globalVar1 = await this.apiService.getFirstAPICall(request); console.log(this.globalVar1); this.globalVar2 = await this.apiService.getSecondAPICall(this.globalVar1); console.log(this.globalVar2); }
Otra forma de solucionar el problema sería hacer la segunda petición en la suscripción de la primera.
Subscribe es asíncrono, lo que significa que no esperará hasta que se ejecute para activar la siguiente línea de su código. En su lugar, debe convertir su .subscribe()
en una promesa. Usualmente usando .toPromise()
.
Luego, puede await
las promesas y asignar el valor a un parámetro que podría pasar a la próxima ejecución.
ejemplo
async ngOnInit() { const res1 = await this.apiService.getData(); // getData() should already be a promise returning a value of type Promise<YourType> const res2 = await this.apiService.getData2(res1); // etc... }
Puede usar el operador rxjs switchMap , luego puede pasar los datos de la primera llamada al observable interno (segunda llamada). entonces no necesita ninguna variable global y no se convierte en una promesa ya que httpClient devuelve un Observable
import { switchMap } from 'rxjs/operators'; ... this.apiService.getFirstAPICall(request).pipe( map(response1 => // edit your data here) switchMap((editedResponse1) => this.getSecondAPICall(editedResponse1) ) ).subscribe()