thomasbishop
thomasbishop

Reputation: 93

How to create an object from constructor data at class initialisation

I want it to be the case that when I instantiate an instance of the class TableCategory, an object is created using the data passed in at instantiation. I want this to happen automatically at instantiation. I don't want have to instantiate the class and then call a method that creates the object. This seems unnecessary cumbersome.

I am using a class because I then want to manipulate the resultant object using getters and setters for multiple instantiations. (In case you wonder why I'm not just using an object in the first place.)

I'm not 100% clear on classes in JS so I'm not sure where I'm going wrong. Please note the object creation is a the product of a function it takes an array passed in at instantiation and an array that is native to the class.

Here's my class:

export class TableCategory {
  constructor(categoryValues = []) {
    this.categoryValues = categoryValues;
    this.categoryKeys = ['alpha','beta','gamma', 'delta'];
    this.categoryData = this.categoryKeys.forEach(function(key, i) { 
      return this.categoryData[key] = this.categoryValues[i]; 
     });
   }
}


Then, for example:

const foo = new TableCategory(['a'. 'b', 'c', 'd']);
console.log(foo.categoryData.beta); // b

Perhaps I need to use static ? Not sure, grateful for any help

Upvotes: 1

Views: 360

Answers (2)

trincot
trincot

Reputation: 350310

forEach does not return anything else than undefined. You can still get the desired object in a functional way, but with Object.fromEntries.

Also, as you say you use a class because you intend to mutate the instance(s) with getters and setters, I don't think it is a good idea to still store the values and keys separately from the third property, which has all key/value information.

You could for instance do this:

class TableCategory {
  constructor(values = []) {
    this._obj = Object.fromEntries(['alpha','beta','gamma', 'delta']
                      .map((key, i) => [key, values[i]]));
  }
  get values() {
      return Object.values(this._obj);
  }
  get keys() {
      return Object.keys(this._obj);
  }
}

let obj = new TableCategory(["this", "is", "a", "test"]);

console.log(obj.values);

Upvotes: 1

Barmar
Barmar

Reputation: 781139

forEach() doesn't return anything. Create an empty categoryData object, and then fill it in in the forEach loop.

Also, you need to use an arrow function to be able to access this in the callback function.

class TableCategory {
  constructor(categoryValues = []) {
    this.categoryValues = categoryValues;
    this.categoryKeys = ['alpha', 'beta', 'gamma', 'delta'];
    this.categoryData = {};
    this.categoryKeys.forEach((key, i) =>
      this.categoryData[key] = this.categoryValues[i]
    )
  }
}

const foo = new TableCategory(['a', 'b', 'c', 'd']);
console.log(foo.categoryData.beta); // b

Upvotes: 1

Related Questions