Comment passer un nouvel appel vers une API lorsqu'une précédente s'est terminée avec succès?

Nov 25 2020

Je suis nouveau dans angular et rxjs, et j'ai le scénario suivant, dans lequel j'ai besoin qu'après un appel à une api soit résolu avec succès pour faire un nouvel appel, dans le contexte de angular / rxjs je ne sais pas comment faire il

handler(): void {
  this.serviceNAme
    .createDirectory(this.path)
    .pipe(
      finalize(() => {
        this.someProperty = false;
      })
    )
    .subscribe(
      (data) => console.log(data),
      (error) => console.error(error.message)
    );
}

Quelle est la bonne façon de passer un nouvel appel à une API lorsqu'une précédente a réussi?

Réponses

2 adrisons Nov 26 2020 at 15:07

Je comprends que vous avez un serviceOneet un serviceTwo. Et vous souhaitez appeler en serviceTwoutilisant les données récupérées à partir de serviceOne.

En utilisant rxjs switchMap, vous pouvez diriger une observable vers une autre.

    handler(): void {
        this.serviceOne
            .createDirectory(this.path)
            .pipe(
                switchMap(serviceOneResult => {
                    // transform data as you wish
                    return this.serviceTwo.methodCall(serviceOneResult);
                })
            )
            .subscribe({
                next: serviceTwoResult => {
                    // here we have the data returned by serviceTwo
                },
                error: err => {},
            });
    }

Si vous n'avez pas besoin de transmettre les données de serviceOneà serviceTwomais que vous avez besoin qu'elles soient toutes les deux complétées ensemble, vous pouvez utiliser rxjs forkJoin .

    handler(): void {
        forkJoin([
            this.serviceOne.createDirectory(this.path), 
            this.serviceTwo.methodCall()
        ])
        .subscribe({
            next: ([serviceOneResult, serviceTwoResult]) => {
                // here we have data returned by both services
            },
            error: err => {},
        });
    }
1 DigitalDrifter Nov 26 2020 at 04:21

En utilisant aysncet awaitvous pouvez faire:

async handler(): void {
  await this.serviceNAme
    .createDirectory(this.path)
    .pipe(
      finalize(() => {
        this.someProperty = false;
      })
    )
    .subscribe(
      (data) => console.log(data),
      (error) => console.error(error.message)
    );

   // Do second api call
}
1 MrkSef Nov 26 2020 at 05:00

Il y a quelques moyens de le faire:

Scénario 1

Vos deux appels d'API de service sont indépendants, vous voulez juste que l'un part, puis le suivant

 const serviceCall1 = this.serviceName.createDirectory(this.path);
 const serviceCall2 = this.serviceName.createDirectory(this.otherPath);

 concat(serviceCall1 , serviceCall2).subscribe({
   next: console.log,
   error: err => console.error(err.message),
   complete: () => console.log("service call 1&2 complete")
 });

Scénario n ° 2

Vos deux appels dépendent l'un de l'autre, vous avez donc besoin du résultat du premier avant de pouvoir démarrer le second

 this.serviceName.getDirectoryRoot().pipe(
   switchMap(root => this.serviceName.createDirectoryInRoot(root, this.path))
 ).subscribe({
   next: console.log,
   error: err => console.error(err.message),
   complete: () => console.log("service call 1 used to create service call 2, which is complete")
 });

Vous aurez besoin du scénario n ° 2 , car fait de cette façon, une erreur dans le premier appel signifiera qu'aucun résultat n'est envoyé au switchMap, et le deuxième appel n'est jamais effectué.