Reputation: 4496
I am new to Angular.io and I have problems with handling with responses from http requests. I am trying to make simple login component.
I wrote simple service :
@Injectable()
export class AuthService {
private url ='http://localhost:3000/user/1';
constructor(private http: Http){}
isLoggedIn: boolean = false;
user : User;
errorMessage:any;
login(username:string, password:string) {
this.getUser(username, password).subscribe((user)=>{
if(user.login===username && password===user.password){
this.isLoggedIn=true;
}
})
}
logout(): void {
this.isLoggedIn = false;
}
getUser(username:string, password:string): Observable<User>{
return (this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError))
}
private extractData(res: Response){
let body = res.json();
return body || {};
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
and login component that calls this service:
public Dologin() {
this.message = 'Trying to log in ...';
this.authService.login(this.model.username, this.model.password)
.subscribe(() => {
this.setMessage();
if (this.authService.isLoggedIn) {
let redirect = '/main';
let navigationExtras: NavigationExtras = {
preserveQueryParams: true,
preserveFragment: true
};
// Redirect the user
this.router.navigate([redirect], navigationExtras);
}
});
}
As You can see I am already consuming Observable on auth service because I need to check login, password. How modify now my Dologin method to call login wait for query to end? Like subscribe but there is no Observable anymore
Upvotes: 1
Views: 598
Reputation: 1463
First of all, don't use a class named User
(I've got an error on the login field). Rename it with MyUser
for example.
You need to use map
instead of subscribe
in the login function and return an Observable<MyUser>
:
login(username:string, password:string) : Observable<MyUser> {
return this.getUser(username, password).map(user => {
if(user.login===username && password===user.password){
this.isLoggedIn=true;
}
return user;
});
}
getUser(username:string, password:string): Observable<MyUser>{
return (this.http.get(this.url).map((r) => {
return r.json() as MyUser;
})
.catch(this.handleError))
}
Explanations :
In the login function, you define the actions that you want to chain but these actions aren't executed yet. The chain will be executed when subscribe()
is called.
First, you get the user (http.get) and then you check the login/password.
Then, you call subscribe()
only once.
Upvotes: 1