Reputation: 161
I have a component named edit-order.component
with the following ts file
export class EditOrderComponent implements OnInit {
constructor(private editOrderSrv: EditOrderService, private route: ActivatedRoute) { }
ngOnInit(): void {
this.editOrderSrv.getOrderById(this.route.snapshot.params.id);
}
}
and in my edit-order-service.service.ts
I have the following code
export class EditOrderService {
order$: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(private http: HttpClient) { }
getOrderById(id: string){
this.http.get('url', {params: {id}}).subscribe(order => {
this.order$.next(order);
}, error => {console.error(error)});
}
}
The client should be able to open more than one edit-order.component
with different id
. In my child.component
I want to subscribe to order$
like that
export class ChildComponent implements OnInit {
order: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.order$.subscribe(order => {
if(order) this.order = order;
})
}
}
But therefore I have to have own instances of the service for every edit-order.component
to not overwrite order$
. How would I achieve that? Or is this not possible? And if it is not possible, what can I do else to achieve my goal?
Upvotes: 1
Views: 1124
Reputation: 57971
Curiosity, why not your function is
getOrderById(id: string){
return this.http.get('url', {params: {id}})
}
And you subscribe to getOrderById
?
You can pipe(catchError) if you wish
Update you can also use a "cache" in the service without use an array of Subject, only an array of object
orders:any={} //create an empty object where we store the result
getOrderById(id: string){
if (this.orders[id])
return of(this.orders[id]
return this.http.get('url', {params: {id}}).pipe(
tap(res=>{
this.orders[id]=res;
})
)
}
Upvotes: 1
Reputation: 2344
It's a really bad idea to create different instances of a service. The purpose of the service is to be singleton and that's how it's designed.
A good way you can use it is to hold a key-value object for every order observable. from parent components pass the this.route.snapshot.params.id
to the child components as input.
(Code untested)
service:
export class EditOrderService {
public orders$: { [orderid: string]: BehaviorSubject<any> } = {};
constructor(private http: HttpClient) { }
getOrderById(id: string): void {
this.http.get('url', { params: { id } }).subscribe(order => {
if (!this.orders$[id]) {
this.orders$[id] = new BehaviorSubject<any>(null);
}
this.orders$[id].next(order);
}, error => { console.error(error); });
}
}
child component:
export class ChildComponent implements OnInit {
order: any;
@Input() orderId: any;
constructor(private editOrderSrv: EditOrderService) { }
ngOnInit(): void {
this.editOrderSrv.orders$[orderId].subscribe(order => {
if(order) this.order = order;
})
}
}
Upvotes: 1