0

I have a Authenticate Class with I would like to return a true or false but with Observable it is async so I am a lost on how to wait for the httpclient to finish.

At the moment the call to isLogin will always return false.

import { Injectable } from '@angular/core';
import { HttpClient , HttpHeaderResponse, HttpHeaders,  } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Subscription } from 'rxjs/Subscription';

class LoginData {
    UserKey: string;
    Password: string;
}

class TokenData {
    token: string;
    datetime: string;
}

@Injectable()
export class Authenticate {

private Url  = 'http://192.168.1.1:6000';

    constructor(private http: HttpClient) {}

    public  isLogin(userkey: string, password: string ): boolean {
    const logindata = new LoginData();
        logindata.UserKey = userkey;
        logindata.Password = password;
    const retval = false;
     this.http.post<TokenData>(`${this.Url}/login`, logindata, {headers: this.getHeader()});
         .subscribe(sub => {
        if(sub.token)
        {
            localStorage.setItem('token',sub.token);
            retval = true;
        }
    } );
         return retval;
    }


}
AlbertK
  • 429
  • 2
  • 8
  • 21
  • what's `sub` your callback return? – Rach Chen Nov 19 '17 at 03:31
  • my subscription on the app.component.ts is this.auth.isLogin('smith', 's12367').subscribe(s => { localStorage.setItem('token', s.token); this.route.navigateByUrl('/mainpage'); }, err => { console.log('Error: ' + err); } ); – AlbertK Nov 19 '17 at 03:48
  • I mean what’s the data return. – Rach Chen Nov 19 '17 at 03:49
  • Maybe the const keyword is making it unable to modify. Try removing const for retval and see. just a thought!! – Aravind Nov 19 '17 at 03:51
  • changing it to let also does not work. What i need is for the http.get to get me the data then I store it in local storage then I return a true of false. I am trying not to use promise. – AlbertK Nov 19 '17 at 04:10
  • Did you check the token in your browser's local storage? – Aravind Nov 19 '17 at 04:41
  • A promise is a better fit for this. It returns the value only after the async is complete – Z. Bagley Nov 19 '17 at 04:59
  • 1
    @Z.Bagley, looks like you have shown me the light. const retpromise = this.http.post(`${this.Url}/login`, logindata, {headers: this.getHeader()}) .map(m => { console.log('Got Token Data'); localStorage.setItem('token', m.token); return true; }) .toPromise(); return retpromise; – AlbertK Nov 19 '17 at 05:44
  • 1
    Possible duplicate of [Angular 2 - Return data directly from an Observable](https://stackoverflow.com/questions/37867020/angular-2-return-data-directly-from-an-observable) – jonrsharpe Nov 19 '17 at 09:04

1 Answers1

-1

It is not possible to do this in a synchronous way in javascript. You have to change your code in the caller of isLogin. There is no other way than to implement some kind of callback. Maybe the async and await keywords will help:

  • Change the signature of the isLogin to public async isLogin(userkey: string, password: string ): Promise <boolean>.
  • Inside of isLogin use the toPromise(). Something like this.http.post<TokenData>(bla bla).toPromise().then(tokenData => {if(tokenData.token){return true;} else {return false; })
  • Change sinature of caller to async and use await keyword: const isLogin: boolean = await component.isLogin('myname', 'mypwd');
yonexbat
  • 2,902
  • 2
  • 32
  • 43