Angular2 Component's "This" Is Undefined When Executing Callback Function

Angular2 component's this is undefined when executing callback function

Use the Function.prototype.bind function:

getMessages() {
this.apiService.getMessages(this.gotMessages.bind(this));
}

What happens here is that you pass the gotMessages as a callback, when that is being executed the scope is different and so the this is not what you expected.

The bind function returns a new function that is bound to the this you defined.

You can, of course, use an arrow function there as well:

getMessages() {
this.apiService.getMessages(messages => this.gotMessages(messages));
}

I prefer the bind syntax, but it's up to you.

A third option so to bind the method to begin with:

export class MainComponent {
getMessages = () => {
...
}
}

Or

export class MainComponent {
...

constructor(private apiService: ApiService) {
this.getMessages = this.getMessages.bind(this);
}

getMessages(){
this.apiService.getMessages(gotMessages);
}
}

Angular7 this is undefined

Prefer to use arrow functions.

For example :

function(arg) {
...
}

become :

(arg) => {
...
}

An arrow function will inherit scope from caller method. So this will be the same.

Your code should look like this:

onDelete(CTId) {
this.confirmDialogService.confirmThis(
"Confirm Delete",
() => {
this.service.deleteContactDetail(CTId).subscribe(
res => {
this.service.refreshList();
this.toastr.warning("Deleted Successfully", "Contact Details");
},
err => {
console.log(err);
this.toastr.error("Failed to Delete");
}
);
},
() => console.log("closed dialog")
);
}

You can read about arrow functions :

  • https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

  • https://www.codementor.io/dariogarciamoya/understanding-this-in-javascript-with-arrow-functions-gcpjwfyuc

Angular2 Undefined Object attribute when using a callback function as Component @Input()

Updated plunkr

In order to pass appOnClick around this way, you need to declare it as a property like so:

export class MyApp {
...
appOnClick = (someText) => {
console.log(someText);
console.log(this.test);
}
}

instead of:

export class MyApp {
...
appOnClick(someText){
console.log(someText);
console.log(this.test);
}
}

Why does object in callback from the subscribe function keeps getting undefined? [SOLVED]

Both this.route.paramMap and this.configuratorService.getMachineDetails will run asynchronously at this point.

Call this.configuratorService.getMachineDetails inside the first subscribe, so that this.configuratorService.getMachineDetails can wait for the itemId to get set.

Something like this:

export class MachineConfiguratorComponent implements OnInit {

itemId: any;
machine: Machine;

constructor(
private configuratorService: ConfiguratorService,
private route: ActivatedRoute
) {}

ngOnInit() {
this.route.paramMap.subscribe(param => {
this.itemId = param.get('id');
this.configuratorService.getMachineDetails(this.itemId).subscribe((res) => {
this.machine = res;
console.log("response in parent is: " + this.machine.description);
});
});
}
}

Update

This is the restcall method in the service:

getMachineDetails(machineId: string):Observable<Machine>{
return this.httpClient.get<Machine> (${this.baseUrl+this.machineUrl}/${machineId});
}

This is the ngOnInit after answers:

ngOnInit() {
this.route.paramMap.subscribe(param => {
this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
// this.machine = res;
console.log("response in parent is: " + res.description);
});
});

}

UPDATE:

Since you want to use the machine as an @Input property to your child component, you'll pass it like this:

<app-machinedetails-overview 
[inputMachine]="machine">
</app-machinedetails-overview>

But since the machine data is being retrieved by making an API call, initially the machine will be undefined. And only when the API call succeeds and you get the machine, then Angular's Change Detection Mechanism will kick in and update [inputMachine]="machine" data binding.

Now, in your MachinedetailsOverviewComponent, ngOnInit only runs once, after the first ngOnChanges. So by the time ngOnInit runs, machine would still be undefined. Hence inputMachine would still be undefined.

So ideally you will get the updated value in ngOnChanges

Make the following changes to your MachinedetailsOverviewComponent:

export class MachinedetailsOverviewComponent implements OnChanges {

@Input() inputMachine: Machine;

constructor() { }

ngOnChanges() {
console.log("child gives: ", this.inputMachine)
}
}

Hope the explanation makes it clear.

angular 2+ refresh callback not working as expected

Your context this inside getSomeData function gets lost when you pass it like below:

ngOnInit() {
this.service.setRefreshCallback(this.getSomeData);
}

To fix this wrap the place where you pass this function inside an arrow function:

ngOnInit() {
this.service.setRefreshCallback(() => this.getSomeData());
}

See red flags for this in the TypeScript documentation.

Object is undefined on event listener callback passed as a method in Angular 2

when you add the eventListener with .addEventListener(), the this context is the Element itself, not your component.

You can fix this easily by using arrow function:

clickHandler = (e) => {
... // your function code here
}


Related Topics



Leave a reply



Submit