2

i am try to create a login app using angular 2 http with promise.

issue is before printing the response object in extractData function in service, "Got response" console is printing from login component. 

So before am getting response from my restful webservice login component below code are executes. This happening only first time i click sign in button. Second time onwards am getting response first then login component code are executes.

Please someone help me to how to wait till response come from webservice.

please find my code below.

Login component

import {Component} from '@angular/core';
import { Router} from '@angular/router';

import {User} from '../model/user';
import {UserService} from '../service/user-service';

@Component({
    selector : 'login-form',
    templateUrl : 'app/template/login.html',
    providers : [
        UserService
    ]
})

export class LoginComponent{

    user: User;

    constructor(private userService: UserService,private router: Router){}

    loginUser(form: any): void {  
        this.userService.loginUser(form.username,form.password).then(user => this.user = user)
        console.log("Got response");
        //console.log(this.user);
        try {
            console.log(this.user.userID);
            console.log(this.user.name);
            console.log(this.user.mobile);
            console.log(this.user.email);
            this.router.navigate(['/']);
        }
        catch(err) {
        }
  }
}

And my service 

import { Injectable }    from '@angular/core';
import { Headers, Http, Response, RequestOptions } from '@angular/http';

import '../rxjs-operators';

import {User} from '../model/user';

@Injectable()
export class UserService{

    private userUrl = 'http://localhost:8080/khalibottle/user/';
    private headers = new Headers({ 'Content-Type': 'application/json' });

    constructor(private http:Http){}

    getUsers (): Promise<User[]> {
    return this.http.get(this.userUrl + "list")
                  .toPromise()
                  .then(this.extractData)
                  .catch(this.handleError);
    }

    loginUser (userName,password): Promise<User> {
       let body = JSON.stringify({ userName, password });
       let options = new RequestOptions({ headers: this.headers });
       return this.http.post(this.userUrl + "login",body,options)
                  .toPromise()
                  .then(this.extractData)
                  .catch(this.handleError);
   }

   registerUser (name,mobile,email,password,roleID): Promise<string> {
    let body = JSON.stringify({ name, mobile, email, password, roleID });
    let options = new RequestOptions({ headers: this.headers });
    return this.http.post(this.userUrl + "register",body,options)
                  .toPromise()
                  .then(this.extractData)
                  .catch(this.handleError);
  }

    private extractData(res: Response) {
        let body = res.json();
      console.log(body);
        return body || { };
    }

    private handleError(error: any) {
        console.error('An error occurred', error);
        return Promise.reject(error.message || error);
    }
}

2 Answers 2

1

Simple: Take the code that you want to wait before executing, and put it inside the .then() call on the promise. Anything and everything that is outside .then() (or .catch(), etc.) will never wait. The success you're seeing on the second and later clicks is an illusion, each time using the results of the previous call.

Like this:

    loginUser(form: any): void {  
        this.userService.loginUser(form.username, form.password).then(user => {
            this.user = user;
            console.log("Got response");
            //console.log(this.user);
            try {
                console.log(this.user.userID);
                console.log(this.user.name);
                console.log(this.user.mobile);
                console.log(this.user.email);
                this.router.navigate(['/']);
            }
            catch(err) {
            }
        });
    }
Sign up to request clarification or add additional context in comments.

Comments

0

Use arrow function to retain this

.then((val) => this.extractData(val))

instead of

.then(this.extractData)

This would also work

.then(this.extractData.bind(this))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.