3

I am trying to implement two sequential HTTP requests in my Angular 2 App. When the user click the login button I want to save in LocalStorage the refresh and access tokens and then execute one more HTTP request in order to get User info. I saw this post but it doesn't work in my case. Angular 2 - Chaining http requests

This was my initial implementation for login and getMe service: How can I merge the requests bellow?

login.component.ts

this.authenticationService.login(this.user.email, this.user.password)
        .subscribe(
        data => {
            // this.alertService.success('Registration successful', false);
            this.router.navigate([this.returnUrl]);
        },
        error => {
            console.log(error);
            this.alertService.error(error);
            this.loading = false;
        });

authentication.service.ts

login(email: string, password: string) {
    let headers = new Headers({
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'Cache-Control': 'no-cache'
    });
    let options = new RequestOptions({ headers: headers });
    return this.http.post(this.config.apiUrl + this.authenticationUrl + '/login',
        JSON.stringify({ email: email, password: password }), options)
        .map((response: Response) => {
            let tokens = response.json();
            if (tokens && tokens.token && tokens.refreshToken) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('tokens', JSON.stringify(tokens));
            }
        });
}

user.service.ts

  getMe() {
    console.log('getMe');
    return this.http.get(this.config.apiUrl + this.usersUrl + '/me', this.jwt()).map((response: Response) => {
        let user = response.json();
        if (user)
            localStorage.setItem('currentUser', JSON.stringify(user));
    });
}
Community
  • 1
  • 1
pik4
  • 1,283
  • 3
  • 21
  • 56
  • first, your function can return a promise or a callback (e.g. Promise). If you use a promise, you can chain the results with (.then, .catch). If you pass a callback, you can chain the methods through callback. – alexsc Mar 15 '17 at 12:41
  • I think that if you use Observable or flatMap, you can avoid this. – pik4 Mar 15 '17 at 12:43
  • 1
    Have a look at http://stackoverflow.com/documentation/rxjs/8247/common-recipes/28035/sending-multiple-sequential-http-requests#t=201703151245534460988 or http://stackoverflow.com/documentation/rxjs/8247/common-recipes/27973/sending-multiple-parallel-http-requests#t=201703151246046358239 – martin Mar 15 '17 at 12:46

1 Answers1

1

You are returning an Observable on your login method, so in your data subscription just call getMe() from your user service.

this.authenticationService.login(this.user.email, this.user.password)
    .subscribe(
    data => {
        // Check to make sure data is what you expected, then call getMe()
        this.userService.getMe();
        this.router.navigate([this.returnUrl]);
    },
    error => {
        console.log(error);
        this.alertService.error(error);
        this.loading = false;
    });

This is a fairly blunt and un-exciting way to approach that problem. As mentioned, mergeMap could serve you well here.

Check out this quick example. I recommend playing around with the Observable data to get a feel for what is happening. The Observable.of are basically acting like fake network request in this case.

http://jsbin.com/pohisuliqo/edit?js,console

Pezetter
  • 2,783
  • 2
  • 22
  • 40