Reputation: 396
I'm unable to get the returned data of my observable which is subscribed in service and the same is called in multiple components.
global.service.ts:
sendProducts(){
return this.getProducts().subscribe(response => {
// perform some logic and return the output
return data;
});
}
getProducts(): Observable {
this.httpClient.get(this.apiUrl).pipe(map(resp => resp));
}
Now from multiple components, I want to access this data from my sendProducts()
method and it is coming as undefined
products.component.ts
getProducts() {
const productsList = this.globalService.sendProducts();
console.log(productsList) => it is coming as undefined.
}
My required output is to get that returned data in components
Thanks in advance.
Upvotes: 1
Views: 901
Reputation: 14750
The problem is that in your service, the sendProducts()
method returns a Subscription
rather than an Observable
.
It is not necessary to subscribe
in order to "perform some logic and return the output". You can instead use many different "pipeable operators" to transform the emitted values and run other code:
map
- transforms data using the function you providetap
- is for doing any type of "side-effect" type of logic. This does not affect what is returnedService:
sendProducts() {
return this.getProducts().pipe(
tap(products => console.log('perform some logic...', products),
map(products => ([...products, { id: 0, name: 'Default Product' }]))
);
}
Then in your component: Component:
getProducts() {
this.globalService.sendProducts().subscribe(
productsList => console.log(productsList)
);
}
But then how do you use that data (productsList
) ?
You may be inclined to do something like this:
public products: Product[];
getProducts() {
this.globalService.sendProducts().subscribe(
productsList => this.products = productsList
);
}
But you could get away with not subscribing at all, even in your component and do something like this:
public products$ = this.globalService.sendProducts();
Then in your template, use the async
pipe to handle subscribing for you:
<ul>
<li *ngFor="let product of products$ | async ">{{ product.name }}</li>
</ul>
The second approach results in less code :-)
Upvotes: 1
Reputation: 1152
getProducts()
should be the one to have the returnglobal.service.ts
. Chances are the flow is asynchronousYour getProducts()
in global.service.ts
should be:
getProducts() {
return this.httpClient.get(this.apiUrl).pipe(map(resp => resp));
}
And you getProducts()
in your product.component.ts
getProducts() {
this.globalService.getProducts().subscribe(
response => {
console.log(response) //see your data here
}, err => console.error(err)
);
}
cleaner code and more understandable
Upvotes: 0