Reputation: 28306
I have the following code. It calls an Angular service which in turn calls a REST service to fetch data from a database.
this.carService.getCarsById(id, searchType)
.subscribe(c => {
this.cars = c;
});
tmpCars = this.cars.map(x => x.color);
console.log("cars: " + tmpCars);
The problem is the lines beginning tmpCars =
and console.log()
execute before the data is returned from the database. How do I stop my code from proceeding until the observable, getCarsById()
an Observable<Car[]>
, returns with all the data?
Upvotes: 0
Views: 32
Reputation: 3772
Asynchronous actions in JS only interact through callbacks. If you want to do anything after the subscription is done, then you'll need to add it as actions on the subscribe
call:
this.carService.getCarsById(id, searchType)
.subscribe(c => {
this.cars = c;
const tmpCars = this.cars.map(x => x.color);
console.log("cars: " + tmpCars);
})
If you want the entire page to literally halt until the request is done then you'll need to make your request a synchronous (blocking) request. This is generally advised against since it negatively impacts page performance. The page could be doing work, but instead it just sits there spinning until the request is finished.
Synchronous requests don't seem to be supported in Angular by default (source).
Alternatively, if you have other miscellaneous actions that you want to have happen when you update cars then you can make the "cars" holder an observable object as a Subject
:
car.component.html:
<div *ngFor="let car of cars$ | async">
<div>Car</div>
<div>Make: {{car.make}}</div>
<div>Model: {{car.model}}</div>
<div>Year: {{car.year}}</div>
</div>
car.component.ts:
...
private carsSubject: Subject<Car[]> = new BehaviorSubject([]);
private cars$: Observable<Car[]> = this.carsSubject.asObservable();
private carsSubscription: Subscription;
constructor(private carService: CarService) {
this.carsSubscription = this.cars$.subscribe(cars => {
const tmpCars = cars.map(x => x.color);
console.log("cars: "+ tmpCars);
});
}
ngOnDestroy() {
this.carsSubscription.unsubscribe();
}
getCars(id, searchType) {
this.carService.getCarsById(id, searchType)
.subscribe(cars => this.carsSubject.next(cars));
}
...
Some of the code can be trimmed down to suit your needs.
Upvotes: 1
Reputation: 871
I do not use Angular but it seems like a normal pub/sub mechanism.
If this one is async, and tmpCars is supposed to be updated with the data from database, you should perform that logic on the subscription callback.
this.carService.getCarsById(id, searchType).subscribe(c => { //MY LOGIC FROM DB});
Hope it helps.
Upvotes: 0