Dans ma page il y a un bouton qui génère un rapport. Ce rapport a besoin de données chargées à l’aide d’un appel http vers un noeud final de repos lors du chargement de la page, mais je n’ai aucune garantie qu’elles soient chargées lorsque l’utilisateur appuie sur le bouton du rapport.
Comment puis-je regarder l'observable pour voir s'il est terminé et, s'il est incomplet, attendre l'action jusqu'à ce que l'appel http soit terminé? Voici une partie du code:
loadCompanies(): void {
this._companyService.getCompanies().subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
generateReport() {
// check if observable that loads companies is completed and do the
// action using companiesModel.
}
Une option consiste à définir un indicateur dans les entreprises de chargement avec les valeurs 'chargement' et 'terminé', et attendre generateReport()
jusqu'à ce qu'il soit terminé, Mais je préférerais une solution utilisant si possible l'API Observable
.
Vous pouvez le faire en utilisant onCompleted
callback dans subscription
. Par exemple, disons que vous affichez la barre de chargement lorsque l'utilisateur appuie sur le bouton de rapport;
loadCompanies(): void {
this._companyService.getCompanies().subscribe(
response => {
this.companiesModel = response;
},
err => {
console.log(err);
//closeLoadingBar();
},
() => {
//do whatever you want
//closeLoadingBar()
}
)
}
generateReport() {
//showLoadingBar()
this.loadCompanies();
}
Si vous obtenez une erreur de votre appel http, la méthode onCompleted
ne sera pas appelée, seule onError
sera invoquée. Si elle réussit, la méthode onCompleted
sera appelée après votre méthode onNext
.
Voici la documentation pour subscribe . J'espère que ça aide!
Une autre solution:
En fait, la fonction subscribe prend trois paramètres:
onNext onError onCompleted
this._companyService.getCompanies().subscribe(
(response) => { this.companiesModel = response; },
(err) => { console.log(err) },
(finally) => { console.log('finally') }
);
Dans ce type de scénario, il est très utile d’utiliser concatMap operator pour s’assurer d’exécuter la prochaine opération uniquement lorsque la précédente l’a fait.
loadCompanies(): void {
this._companyService.getCompanies()
.concatMap(companyList => this.getObservableGenerateReport(companyList))
.subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
//Create observable to generate the report
getObservableGenerateReport(response: any): Observable<myReportList> {
return Observable.create(observer => {
if (generateReport().isSuccessful) {
observer.next(myReportList);
observer.complete();
} else {
console.log(err, 'Ups, something was wrong!');
observer.next({});
observer.complete();
}
});
}
Méthode
finally()
Invoque une action spécifiée après la séquence observable source se termine gracieusement ou exceptionnellement.
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/finally.md
La solution que j’ai suggérée est d’utiliser un observable partagé, d’enregistrer la requête en tant qu’observable à chaud. Ainsi, lorsque vous cliquerez sur le bouton de rapport, il attendra la requête ou le générera immédiatement si la requête est complète.
public companiesModel: Company[];
/** pending request, hot Observable (will emit immediately if complete) */
private companiesRequest: Observable<Company[]>;
constructor(
private _companyService: CompanyService
) {}
public ngOnInit(): void {
this.loadCompanies();
}
public generateReport(): void {
if (this.companiesRequest) {
// will not make an other network request
this.companiesRequest.subscribe(
response => {
// action using companiesModel.
},
err => console.log(err)
);
}
}
private loadCompanies(): void {
this.companiesRequest = this._companyService.getCompanies().pipe(shareReplay());
this.companiesRequest.subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
https://stackblitz.com/edit/check-if-an-observable-is-completed?file=src%2Fapp%2Fapp.component.ts
Mise à jour: vous pouvez aller un peu plus loin et rendre l’UI async https://stackblitz.com/edit/check-if-an-observable-is-completed-async-ui?file=src%2Fapp % 2Fapp.component.html