Reputation: 324
I am new to typeScript and Angular8
I have the following code that is to get data from a web service. Currently, it returns null
but if I add console.log(this.service_type)
to the line before the end of the if (user.status == 200) {
block, I get the right data, how do I return the correct data
what am I not doing or doing wrong?
import { User } from '../_models/user';
import { Router } from '@angular/router';
import { ApiService } from './api.service';
import { ServiceType, Donations, Betting, Topup } from '../_models/data';
@Injectable({
providedIn: 'root'
})
export class CheckService {
constructor(
private apiService: ApiService,
private router: Router
) {}
service_type: ServiceType = null;
donations: Donations = null;
betting: Betting = null;
services: Topup = null;
getReward() {
this.apiService.getRewardServices().subscribe(
user => {
if (user.status == 200) {
this.service_type = user.data.service_type;
this.donations = user.data.donations;
this.betting = user.data.betting;
this.services = user.data.services;
}
}
);
return {service_type: this.service_type, donations: this.donations, betting: this.betting, services: this.services}
}
}```
Upvotes: 0
Views: 41
Reputation: 142
When the getRewards()
method is called, the following things happen:
What you can do, instead of subscribing to data in the method, return observable object and use it with async
pipe.
Service:
export class CheckService {
constructor(
private apiService: ApiService,
private router: Router
) {}
rewardObject$: Observable<any>;
getReward() {
this.rewardObject = this.apiService.getRewardServices().pipe(map(user => {
if (user.status == 200) {
return {
service_type: user.data.service_type,
donations: user.data.donations,
betting: user.data.betting,
services: user.data.services,
};
return null;
}
}));
}
}
Template:
<ng-container *ngIf="(rewardObject$ | async) as reward">
<span>{{reward.service_type}}</span>
</ng-container>
Upvotes: 1
Reputation: 851
You are hitting a road-block where most developers get stuck when first being introduced to the concept of asynchronous programming and reactive programming. You have some method, getRewardServices
, which returns some Observable
, which your service subscribes to, and performs the callback for each element this observable emits (you can read more here). The key problem is in this line:
return {service_type: this.service_type, donations: this.donations, betting: this.betting, services: this.services}
which can be executed before the observable emits a user object. The proper way to tackle this would be to map the observable into the object you want to return, and return the observable itself. It will be the responsibility of the outer service/component to unwrap the observable and handle the asynchronous event. Something like this:
getReward(): Observable<any> {
return this.apiService.getRewardServices().pipe(
map(user => {
if (user.status == 200) {
this.service_type = user.data.service_type;
this.donations = user.data.donations;
this.betting = user.data.betting;
this.services = user.data.services;
return {service_type: this.service_type, donations: this.donations, betting: this.betting, services: this.services}
}
return some_other_error_value;
});
}
Upvotes: 1