Reputation: 860
I have called a single service in angular but have never called multiple services. In the image I have attached the requirement is to add the client and group values into a table called clientGroup Xref. Also the client, Clientrole, ClientKey in different table (ClientService will do that) . I want to know how can I call clientservice and clientgroup Xref service both at the same time on create button click.
This is the code I tried so far
import { Router } from '@angular/router';
import { AuthService } from './auth.service';
import {PESAuthService} from './pes_auth.service';
import { Component, OnInit, Injectable } from '@angular/core';
import { Http, Request, RequestMethod, RequestOptions, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import {Client} from './../../shared/models/Client';
@Injectable()
export class ClientService implements OnInit {
private appContent = 'application/json';
private _router: Router;
private baseUrl = 'http://localhost:5050/api/v1/';
//Constructor to initialize authService to authenticate user, http to send the CRUD request and Router for the resource
constructor(private authService: AuthService, private http: Http,private router: Router,private pesauthservice: PESAuthService) {
}
ngOnInit() {
}
//For creating a user Client,Key,Firstname and lastName has to be passed
// created: Date
create(client: string, clientkey: string, clientrole: string) :Observable<boolean> {
//createAuthenticatedRequest is called before sending the Http request
let request = this.createAuthenticatedRequest(JSON.stringify({client: client, clientkey: clientkey, clientrole: clientrole}),RequestMethod.Post);
return this.http.request(request).map(r=>{
r.ok;
}).catch((error: any) =>{
return Observable.throw(error);
});
}
update(id: number,client: string, clientKey: string, clientRole: string, created: Date) :Observable<any> {
let request = this.createAuthenticatedRequest(JSON.stringify(
{id:id,client: client, clientKey: clientKey, clientRole: clientRole, created: created}),RequestMethod.Put,id.toString());
return this.http.request(request).map(r=>{
r.json;
console.log(r);
}).catch((error: any) =>{
console.log(error);
return Observable.throw(error);
});
}
delete(client: string, clientkey: string, clientrole: string, created: Date):Observable<boolean> {
let request = this.createAuthenticatedRequest(JSON.stringify({client: client, clientkey: clientkey, clientrole: clientrole, created: created}),RequestMethod.Delete);
return this.http.request(request).map(r=>{
r.ok;
}).catch((error: any) =>{
return Observable.throw(error);
});
}
//Read method takes an optional input id, If id is not passed to read it will get the entire list , else it will get the record with specified id
read(id?: Number):Observable<any> {
id = (id == undefined) ? 0 : id ;
if (id >0)
// Get single resouce from Collection
var request = this.createAuthenticatedRequest(null,RequestMethod.Get, id.toString());
else
// Get the entire collection
request = this.createAuthenticatedRequest(null,RequestMethod.Get, id.toString());
return this.http.request(request).map(r=>{
console.log(r.text());
return JSON.parse("[" + r.text() + "]")[0];
}).catch((error: any) =>{
return Observable.throw(error);
});
}
//This method accepts json of the attribtes client,key,firstname and lastName and request method(Post/Get/Put/delete) and
//an optional parameter id , This method's return type is Request
createAuthenticatedRequest(json : string, reqMethod: RequestMethod, optionalparam?: string) : Request{
//checks if the user is authenticated user with authentication service method isAuthenticated
if (this.authService.isAuthenticated()) {
if( this.pesauthservice.isPESAuthenticated())
{
console.log('authenticated');
//creating a request object with method,url and body consisting of client,key,firstname and lastName and optional parameter id
optionalparam =(optionalparam==undefined || optionalparam =='0') ? "" : optionalparam;
const request = new Request({
method: reqMethod,
url: this.baseUrl + 'clients/' + optionalparam +"",
body: json
});
//request header Authorization is added to specify that the request has an authenticated token
request.headers.append('Authorization', 'Bearer ' + this.pesauthservice.getToken());
request.headers.append('Content-Type', this.appContent);
request.headers.append('Accept', this.appContent);
return request;
}
else {
console.log('notauthenticated');
this._router.navigateByUrl('/login');
}
}
else {
console.log('notauthenticated');
this._router.navigateByUrl('/login');
}
}
}
Can someone tell me on the approach I should consider.
Upvotes: 4
Views: 11767
Reputation: 222522
There are many ways you can do this.You can use Observable.forkjoin
or Observable.merge
Object.forkJoin
will wait until all requests are completed and then you can build a single list with this results;
Example for forkjoin
const allrequests = Observable.forkJoin(
this.http.get('https://testdb1.com/.json').map((res: Response) => res.json()),
this.http.get('https://testdb2.com/.json').map((res: Response) => res.json())
)
allrequests.subscribe(latestResults => {
const [ data_changes , data_all ] = latestResults;
});
Upvotes: 5
Reputation: 708
If you want to run the 2 requests concurrently and get the combined result when both of the complete you can use combineLatest
like so:
const updateClient$ = this.clientService.update(...);
const updateGroup$ = this.clientXrefGroupService.update(...);
Observable.combineLatest(updateClient$,updateGroup$)
.subscribe(combinedResult => {
// Here combinedResult is an array.
// Index 0 contains response from updateClient$ request
// Index 1 contains response from updateGroup$ request
});
If you want to run the requests one after the other (for example if you want to use the result of the first call in order to make the second) you can use concatMap
:
updateClient$.concatMap(resultOfUpdateClient => {
return updateGroup$;
}).subscribe(resultOfUpdateGroup => {
// Do your stuff here
});
Last, if you want to run one after the other but need both results in the final subscription then you can use a combination of the above:
updateClient$.concatMap(resultOfUpdateClient => {
return Observable.combineLatest(updateGroup$, Observable.of(resultOfUpdateClient));
}).subscribe(combined => {
// Here combined is an array containing the result of both calls.
});
For more information see: combineLatest, concatMap.
Upvotes: 3
Reputation: 1964
The real question is why do it in different endpoints? If one of the two will fail, or the last one to be precise? how do you rollback the previous transaction?
consider this action as an atomic one. post all data to the server, let the server split it to tables or whatever needs to be done.
Upvotes: 0