I have a service that starts by executing the getName function, and then when some data gets into the else block of the getPlace function, instead of a regular object, I get a subscriber (as you can see in the screenshot), although in theory I subscribe to changes where I assign values. it can be fixed?

- 21
- 2
-
1welcome, please put your code in text mode. – Ali Bigdeli Aug 14 '20 at 20:02
3 Answers
As others have said, you can't treat an http request (the http.get) as procedural code. The http request is asynchronous and the code within the .pipe()
method is only executed after the data is returned from the server.
So your getPlace()
method, won't be able to simply return data
by calling the _getPlace()
method.
Instead of fighting against the way this works and trying to "fix" it. I would suggest that you handle both as Observables.
My code in a similar situation looks like this:
Service
import { Observable, of, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
getProducts(): Observable<IProduct[]> {
if (this.products) {
return of(this.products);
}
return this.http.get<IProduct[]>(this.productsUrl)
.pipe(
tap(data => console.log('All Products', JSON.stringify(data))),
tap(data => this.products = data),
catchError(this.handleError)
);
}
Component
this.productService.getProducts().subscribe({
next: (products: IProduct[]) => {
this.products = products;
},
error: err => this.errorMessage = err
});
Here, if the data has already been cached, it uses the RxJS of
operator to convert the data back into an Observable.
That way you can subscribe to the result of getProducts and you'll get the cached data OR the retrieved data.
NOTE: Another option is to use RxJS declaratively and leverage the RxJS shareReplay(1)
operator to automatically provide the caching for you. For more information on this technique, check this out: https://www.youtube.com/watch?v=Z76QlSpYcck&t=517s

- 57,520
- 12
- 104
- 129
You have to subscribe the function for getting the value
public nameList :any;
this.getPlace(placeId).subscribe(data => {
//data hold your expected response
this.nameList =data;
});

- 2,717
- 1
- 15
- 26
-
Then I get the error This.getPlace (...). Subscribe is not a function. Actually, I have the same logic in the getplace function, but if I don't explicitly assign let data = this._getPlace (placeId) .subscribe ... but write let data; and then under it a subscription to getplace, then 3 undefined will arrive in data @Jobelle – Вячеслав Салоид Aug 14 '20 at 17:02
Observable are asynchronous and javascript use a single thread environment. If the javascript thread detects any async task, the task are handed to enclosing environment(Browser etc.) to execute it in a seperate thread. So your code runs like this.
- Main Thread call this._getPlace()
- Checks the statement this._getPlace() and hands off the execution to other thread.
- Main Thread return data variable (which is null) - this happens before Step2 is finished.
That's why the data returned is null.
To solve your problem, usemap
instead of subscribe
if(this._place.has(placeId)){
return this._places.get(placeId)
} else {
let data: any = this.getPlace(placeId).map( place => {
//do something here
//return something
}).first()
return data;
}

- 304
- 1
- 12
-
Than i got an error Property 'map' does not exist on type 'Observable
> @acer23 – Вячеслав Салоид Aug 14 '20 at 17:07