Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 forEach cant read property

How can I call this.firms within a data forEach()?

I know how to do this in Angular1, but not with my current project in Angular 2.

Currently it works fine outside of the forEach, but not within.

 console.log(this.firms[0].name); // works
    var a = 0;
        console.log("--------------");

    data.forEach(function (eachObj) {
      console.log("firms check!");
      console.log(this.firms); // not working
      a = a + eachObj.income; 
      eachObj.name = this.firms[data.firmid - 1].name; // wont work
    });

Error:

Cannot read property 'firms' of undefined
like image 576
maria Avatar asked May 11 '17 11:05

maria


3 Answers

You can try to make the data to be and array

like so :

Array.from(data).forEach((eachObj) => {
    console.log("firms check!"); 
    console.log(that.firms);
    eachObj.name = that.firms[data.firmid - 1].name;
})

This will work as well

like image 38
Acika00mk Avatar answered Nov 18 '22 07:11

Acika00mk


The context this is not injected in the anonymous function called by the forEach(). That's why this is undefined.

You can either use the arrow function if you're using ES6 features, as it keeps the context in the function:

data.forEach(eachObj => {
  console.log("firms check!");
  console.log(this.firms);
  a = a + eachObj.income; 
  eachObj.name = this.firms[data.firmid - 1].name;
});

Or simply bind the context directly:

data.forEach(function (eachObj) {
  console.log("firms check!");
  console.log(this.firms);
  a = a + eachObj.income; 
  eachObj.name = this.firms[data.firmid - 1].name;
}.bind(this));

Edit:

As mentioned by zeroflagL, you could simply pass the context to the forEach():

data.forEach(function (eachObj) {
  console.log("firms check!");
  console.log(this.firms);
  a = a + eachObj.income; 
  eachObj.name = this.firms[data.firmid - 1].name;
}, this);
like image 136
Erazihel Avatar answered Nov 18 '22 08:11

Erazihel


That's the basic example for scope in javascript. Inside your function this refers to the context of the function itself. The outside world isn't accessable.

Since you're using Typescript with angular you can just use an arrow function:

data.forEach((eachObj) => {
  console.log("firms check!");
  console.log(this.firms); // not working
  a = a + eachObj.income; 
  eachObj.name = this.firms[data.firmid - 1].name; // wont work
});

This will preserve the scope and your this is available inside it. In plain javascript you could do something like this:

var that = this;

data.forEach(function (eachObj) {
  console.log("firms check!");
  console.log(that.firms); // not working
  a = a + eachObj.income; 
  eachObj.name = that.firms[data.firmid - 1].name; // wont work
});
like image 1
malifa Avatar answered Nov 18 '22 09:11

malifa