Reputation: 239
This might be a basic question. but I am new to angular services(promises,observable etc).
basically, I have a button(login) in login page , once user clicks on that button I want to validate and generate token. once the token is assigned field on service, then I will redirect to some page(Home page). But what is happening now is, when I made a function call to angular service function, before it gets(asynchronously) the token itself my page is redirecting.
app-data-service
`
import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class AppDataServiceService {
tokenGenerated:any='';
constructor(private http: HttpClient) {
}
getData(){
console.log("Started.. in service");
this.http.get('http://host/url').toPromise()
.then(this.extractData);
}
private extractData(res: Response) {
console.log("completed.. in service");
this.tokenGenerated=res;
return res;
}
}
`---------------------------------------------------
login component
import { Component, OnInit } from '@angular/core';
import { AppDataServiceService } from '../app-data-service.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-login-component',
templateUrl: './login-component.component.html',
styleUrls: ['./login-component.component.css']
})
export class LoginComponentComponent implements OnInit {
constructor(private dataService:AppDataServiceService,private router:Router) {
}
ngOnInit() {
}
submit(){
this.dataService.getData();
console.log('after executing service');
this.router.navigate(['/view']);
};
}
-------------------------------------------------------------
login html
<div class="container">
<label><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" >
<label><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" >
</div>
<input type="button" (click)='submit()' value="Login" name="submit"/>
console output in browser:
Started.. in service
after executing service
completed.. in service
Can you help me to let http call wait till its completion. I am not sure if that is the way to use promise to make the call synchronous.
Upvotes: 1
Views: 13665
Reputation: 1143
Use synchronous http request as below
var request = new XMLHttpRequest();
request.open('GET', "https://domain/api", false);
request.send(null);
const response = JSON.parse(request.responseText);
Would not be able to take advantage of DI using HttpClient
and hence should be used absolutely when required.
Upvotes: 1
Reputation: 18281
You should return a promise (or Observable) from your service, and subscribe to that in the component.
Without doing so, the component has no way of knowing when your asynchronous code has finished executing, so it prints that log statement immediately
Change the service like so:
getData(){
console.log("Started.. in service");
return this.http.get('http://host/url').toPromise()
.then(res => this.extractData(res));
}
Then in the component
submit(){
this.dataService.getData().then(() => {
console.log('after executing service');
this.router.navigate(['/view']);
};
};
Upvotes: 7