So i'm quite new to angular and also to observables in general. I know how to deal with promises but I would like to be more comfortable with the Observable side.
I'll try to keep it short but here's the setup:
In order to reduce the amount of calls made to the server, I created a package service that basically packages what would be multiple requests into a single one.
A component would ask multiple data services to refresh their store if their cache aren't up to date. Every data services that needs an update from the server adds a request to the package. When ready, the component sends the package to the package service which in turn will send the request to the server.
When the server replies with data, I need every data services to update their store with the new data pertaining to their single requests and then notify the component that everything has completed.
Here's how I would do it with promises :
1) Component builds a package from every needed data services.
2) Component sends it to the package service that returns a promise.
3) The package service sends the request(s).
4) When the server replies, the package service dispatches the response to every data services registered in the package.
5) The package service resolves its promise only when every involved data services are done updating their stores.
6) The component deals with the resolved/rejected promise.
So trying to convert this to an observable pattern I get this:
Component:
let thePackage = this.packageService.createPackageInstance();
this.service1.loadData( thePackage );
this.service2.loadData( thePackage );
this.packageService.sendPackage( thePackage ).subscribe( () => console.log("Success"), (err) => console.error( err ) );
Service1 and Service2:
loadData( thePackage: Package ) {
let needUpdate = this.GetCacheIsUpToDate();
if( needUpdate ) {
let params = {
"param1": true
};
//This would return a promise in a promise chain pattern.
let callback = ( ( response:any ) => {
//[...]
//Do update the data store and notify subscribers.
return Promise.resolve(); //The only way I know to make it work.
});
this.packageService.createRequest( thePackage, 100, 1, params, callback );
}
}
PackageService:
createPackageInstance(): Package {
return new Package({/* Some params */});
}
createRequest( thePackage:Package, theModule:number, operation:number, params:any, callback:Function ):void {
let data = JSON.stringify( params );
let request = new Request({
"id": Utils.generateGUID(),
"theModule": theModule,
"operation": operation,
"data" : data,
"callback": callback
});
thePackage.requests.push( request );
}
sendPackage( thePackage ): Observable<PackageResponse>{
//Assume some variables like 'someUrl' to be setup
//[...]
let httpObs = this.http.post( someUrl, formData, someOptions ).map( response => {
return response.json();
});
return httpObs.flatMap( ( response ) => {
let pAll = [];
thePackage.requests.forEach( request => {
pAll.push( request.callback( response ) );
});
return Observable.fromPromise( Promise.all( pAll ) ); //This is really ugly
});
}
EDIT: Edited some code to show my current version that works with promises.