karthik gorijavolu
karthik gorijavolu

Reputation: 860

Calling multiple services for a single component in Angular

enter image description here

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

Answers (3)

Sajeetharan
Sajeetharan

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

Siri0S
Siri0S

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

Avi
Avi

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

Related Questions