lesnar
lesnar

Reputation: 2480

Angular 2: Http asynchronous call

I am using Http Service from Angular2 :

My login component:

    doLogin() {
        this.authenticationService.inValidateSession();    
 this.authenticationService.userConfiguration=this.httpService.login(this.user.email,this.user.password)
        this.router.navigate(['/site']);

    }

HttpService

login(username:string,password:string) {
     let headers = new Headers();
     this.createAuthorizationHeader(headers,username,password);
     this.http.get(this.url,{headers:headers}).subscribe(this.extractData,this.handleError);
     return this.configFromLogin;  
}

private extractData(res: Response) {
  if(res.status==200){
    let body = res.json();
    var result={"config":body,
                "x-xsrf-token":res.headers.get('x-xsrf-token')};
    this.configFromLogin=result;
  }
  else{
    //console.log(error);
    // throw exception or use this.error() method
  }
}

Since Server provides Token authentication which we need to use for all the Post Requests, i save it in Session.

My Problems or Doubts:

  1. When i debug doLogin() codes get executed first (saveInSession) even before HttpService extractData is executed. Why ? i know Http get is async call but how can i make doLogin wait ?
  2. In HttpService i am checking if response is 200 then i am saving it otherwise i want to throw error and use the HandleError method , which i am using in subscribe method of Observable. Is it possible ?

Please help me with above two problems, in case of questions i am available to answer.

Thanks

Upvotes: 1

Views: 1711

Answers (1)

Supamiu
Supamiu

Reputation: 8731

You problem is that you don't wait for the http request to be complete before calling router.navigate.

Your service should return an observable in order to tell the calling component that the request is finished and everything is good to navigate.

login component

    doLogin() {
        this.authenticationService.inValidateSession();    
        this.httpService.login(this.user.email,this.user.password).subscribe(result => {
            this.authenticationService.userConfiguration=result;
            this.router.navigate(['/site']);
        }, 
        error => {
            console.error(error);
        });
    }

HttpService

login(username:string,password:string):Observable<any> {
     let headers = new Headers();
     this.createAuthorizationHeader(headers,username,password);

     //We will return the http observable, mapped with our auth function
     return this.http.get(this.url,{headers:headers}) 
     .map(this.extractData);//We bind the authentication process on the observable
}

private extractData(res: Response) {
    if(res.status !== 200){
        throw new Error('Not a 200, bla bla details');
    }
    let body = res.json();
    var result={"config":body,
                "x-xsrf-token":res.headers.get('x-xsrf-token')};
    return result;
}

EDIT: I added a throw in the extractData method, it allows you to throw an error which will be catched by rxjs and handled in the onError parameter of subscribe.

Upvotes: 1

Related Questions