I am trying to call a method defined in my Angular service in my component.
My Angular service method:
getGadgetDetailById(id: number)
{
return this.gadgets.find(gadget => gadget.id === id);
}
Here 'gadgets' is obviously an array of type 'Gadget'.
Gadget model type:
export interface Gadget {
id: number;
name: string;
distributor: string;
description: string;
price: number;
available: boolean;
rating?: number;
}
I am trying to call the service method in my component as:
gadget:Gadget|undefined;
gadgetId:any;
ngOnInit(): void {
this.ar.paramMap.subscribe(params => {
this.gadgetId=params.get('id');
});
this.getGadgetDetailById(this.gadgetId);
}
getGadgetDetailById(id: number)
{
this.gadget = this.gService.getGadgetDetailById(id);
}
I am getting an error on 'next':
No overload matches this call.
Overload 1 of 2, '(observerOrNext?: Partial<Observer<Gadget | undefined>> | ((value: Gadget | undefined) => void) | undefined): Subscription', gave the following error.
What is it?
Your problem is here:
ngOnInit(): void {
this.ar.paramMap.subscribe(params => {
this.gadgetId=params.get('id');
});
this.getGadgetDetailById(this.gadgetId);
}
Because the subscribe
callback isn't called immediately, this.getGadgetDetailById(this.gadgetId)
is called, then this.gadgetId=params.get('id');
runs. This means that this.gadgetId
is undefined
at the time thatthis.getGadgetDetailById
is run, so you're searching gadgets
for a gadget with an undefined
id
.
The simple fix is just to move the call to this.getGadgetDetailById
into the subscribe
callback:
ngOnInit(): void {
this.ar.paramMap.subscribe(params => {
this.gadgetId=params.get('id');
this.getGadgetDetailById(this.gadgetId);
});
}
This kind of just kicks the problem down the road though, since now this.gadget
is being assigned asyncronously, so access to this.gadget
may fail if it's accessed before it's assigned. If you want to protect against that, you could make this.gadget
an Observable as well:
gadget: Observable<Gadget | undefined>;
ngOnInit(): void {
this.gadget = this.ar.paramMap.pipe(
map((params) => this.gService.getGadgetDetailById(params.get('id'))),
);
}
Now this.gadget
can be subscribed to, and it will definately, always exist (although it will delay emitting a gadget until the paramater subject has fired.