Reputation: 55
Ive already searched a solution but none of them works.
After clicking on a button edit it redirects me to edit-event and I'm getting :
ERROR TypeError: Cannot read property 'categories' of undefined
ngOnInit() {
this.eventService
.getEventById(this.route.snapshot.params.id)
.subscribe((ev) => this.event = ev);
After the subscribe if I do this : console.log(this.event) it returns me undefined.
Wherease .subscribe(console.log(ev));
returns me an object.
Don't know why this.event = ev
doesn't work Ive already used this in another component and the mapping works.
The service :
getEventById(id) {
return this.httpClient.get<EventsDto>(this.urlevent + '?id=' + id);
}
In edit-event.component.html, {{event.name}} is printed how is this possible
if this.event is undefined as we've seen before with : .subscribe((ev) => this.event = ev)
Upvotes: 0
Views: 408
Reputation: 1771
tl;dr - Group your asynchronous logic by calling this.http.get()
inside of the button press function and apply any downstream logic within its subscribe()
method
As you are dealing with asynchronous code, you have to take extra care to ensure that the asynchronous functions (e.g. your this.httpClient.get
request) have returned the data before you try and interact with it, display it etc.
As you quite rightly mentioned, your .subscribe(console.log(ev))
is correctly logging data but your synchronous console.log(ev)
is not. This is due to the fact that the sychronous console.log(ev)
will be executed immediately after your this.httpClient.get()
has been called. As it takes some time for the asynchronous data to be returned, the variable ev
is still undefined
at the point in time that the sychronous console.log(ev)
is fired. Calling console.log(ev)
from within your subscribe()
block instead waits specifically for the data to be returned from the this.httpClient.get()
before executing, guaranteeing that ev
will have the data you requested (or an error).
With that in mind, a simple way to mitigate your issue would be to call the this.http.get()
request inside the button click event and include any downstream functionality within the .subscribe()
function. This will allow the compiler to guarantee that some data is available at the time that the subsequent functions are called.
.html
<button (click)="buttonClick()></button>
.ts
buttonClick() {
this.eventService
.getEventById(this.route.snapshot.params.id)
.subscribe(ev => {
this.event = ev
// your code here, e.g. createEventsDto(ev)
});
Upvotes: 1