Reputation: 557
I want a service that would return the observable and set a value to field in the same method.
Now my userService.getUserDetails()
method looks like this:
private requestUrl: string;
private bic: string;
private id: string;
private name: string;
getUserDetails(): Observable<User> {
this.bic = 'aaa';
this.id= '123';
this.requestUrl = `${configs.api}v1/bics/` + encodeURIComponent(this.bic) + `/ids/` + encodeURIComponent(this.id) + `/users`;
const userObservable = this.http.get<User>(this.requestUrl).pipe(catchError(this.handleError));
userObservable.subscribe(data => this.name = data.name);
return userObservable;
}
I want to do two things when getUserDetails
is called:
1) return Observable<User>
2) set the name
value so I could access it later in other classes by injecting this service in constructors, without calling the http request again. I think I want to have something like this:
getName() {
return this.name;
}
So I'm not sure about the subscribe, because I'm getting undefined after try to use the value. What is the best approach here?
Upvotes: 0
Views: 1444
Reputation:
Try to use the observable like this:
public name: string;
public bic: string;
public id: string;
public getUserDetails(): Observable<User> {
this.bic = '...';
this.id = '...';
this.requestUrl = `${configs.api}v1/bics/` + encodeURIComponent(this.bic) + `/ids/` + encodeURIComponent(this.id) + `/users`;
return this.http.get<User>(this.requestUrl).pipe(catchError(this.handleError));
}
Ideally, this method is in a service and does nothing else but to return the observable and do error-handling if needed.
In your component you could have this:
constructor(private readonly _yourService: YourService) {}
public ngOnInit(): void {
this.getUserDetails();
console.log(this._yourService.name) // can be undefined, since the observable is asynchronous and probably isnt finished yet
}
public getUserDetails(): void{
this._yourService.getUserDetails().subscribe(
data => {
this._yourService.name = data.name;
// start doing other things, this.name should be defined, if your service returned the data correctly.
}
)
}
Alternatievly, you can also do all of this in your service, it's really your choice of design.
Upvotes: 1
Reputation: 57981
use "tap", in your service
name:any;
const userObservable = this.http.get<User>(this.requestUrl).pipe(
tap((res)=>{
this.name=res;
}),
catchError(this.handleError)
);
Sometimes it's used a kind of "cache"
name:any;
const userObservable = (this.name)?of(name):
this.http.get<User>(this.requestUrl).pipe(
tap((res)=>{
this.name=res;
}),
catchError(this.handleError)
);
So, you always can subscribe to the function, the first time, make the call to http, the second use the value of name -of(name)
return an observable
Upvotes: 0