3

I have users array (of objects) inside a JavaScript class. Every user has an isActive property. I have created a setUserStatus that is intended to modify the mentioned property in every user:

class usersGroupMake {

  constructor() {
  
    this.isGroupActive = true;

    this.groups = {
      groupId: 1,
      users: [{
          firstName: 'John',
          lastName: 'Hopkins',
          isActive: true
        },
        {
          firstName: 'Tim',
          lastName: 'Cook',
          isActive: true
        },
        {
          firstName: 'Marry',
          lastName: 'Smith',
          isActive: true
        }
      ]
    };
    
    this.setUserStatus = function(){
      this.groups.users.forEach(function(user) {
        user.isActive = user.isActive && this.isGroupActive;
      });
    }
  }
}

var userGroup1 = new usersGroupMake();
userGroup1.setUserStatus();
console.log(userGroup1.groups.users);

In this function, as you can see, I am trying to use the property isGroupActive of my class but, as far as I can see, JavaScript tries to identify isGroupActive as a property of the current user in the iteration.

What shall I do to be able to use this.isGroupActive from the top of my class insread?

Note: my question is not a duplicate, it is a lot more specific then the question indicated as a dplicate.

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • 2
    Use [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – Liam Sep 24 '19 at 15:38
  • Possible duplicate of [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Liam Sep 24 '19 at 15:39
  • In your callback, `this` is not the current user, it's undefined. – georg Sep 24 '19 at 15:55

3 Answers3

4

Two things you could do:

First, you could save a reference to this in the function before the .forEach():

this.setUserStatus = function(){
  let group = this;
  this.groups.users.forEach(function(user) {
    user.isActive = user.isActive && group.isGroupActive;
  });
}

Second, you could use an arrow function:

this.setUserStatus = function(){
  this.groups.users.forEach(user => {
    user.isActive = user.isActive && this.isGroupActive;
  });
}

edit — I guess a third way would be to take advantage of the .forEach() API and provide an explicit this:

this.setUserStatus = function(){
  this.groups.users.forEach(function(user) {
    user.isActive = user.isActive && this.isGroupActive;
  }, this);
}
Pointy
  • 405,095
  • 59
  • 585
  • 614
2

You could take thisArg of Array#forEach.

class usersGroupMake {

  constructor() {
  
    this.isGroupActive = true;

    this.groups = {
      groupId: 1,
      users: [{
          firstName: 'John',
          lastName: 'Hopkins',
          isActive: true
        },
        {
          firstName: 'Tim',
          lastName: 'Cook',
          isActive: true
        },
        {
          firstName: 'Marry',
          lastName: 'Smith',
          isActive: true
        }
      ]
    };
    
    this.setUserStatus = function(){
      this.groups.users.forEach(function(user) {
        user.isActive = user.isActive && this.isGroupActive;
      }, this); // <--
    }
  }
}

var userGroup1 = new usersGroupMake();
userGroup1.setUserStatus();
console.log(userGroup1.groups.users);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

This is another way:

class usersGroupMake {
    
      constructor() {
      
        this.isGroupActive = true;
    
        this.groups = {
          groupId: 1,
          users: [{
              firstName: 'John',
              lastName: 'Hopkins',
              isActive: true
            },
            {
              firstName: 'Tim',
              lastName: 'Cook',
              isActive: true
            },
            {
              firstName: 'Marry',
              lastName: 'Smith',
              isActive: true
            }
          ]
        };
        
        this.setUserStatus = function(){
          this.groups.users.map((user)=>{
            user.isActive = user.isActive && this.isGroupActive;
          });
        }
      }
    }
    
    var userGroup1 = new usersGroupMake();
    userGroup1.setUserStatus();
    console.log(userGroup1.groups.users);
Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
Nipu
  • 7
  • 6