Robert Samarji
Robert Samarji

Reputation: 113

Calling a method within a dynamically named object

I am trying to invoke a method of a dynamically named object.

I have a few objects each containing a method named 'getWeight'. I need to invoke this method of a subset of these objects. However, the subset of objects depends on user inputted info, which is why I'm attempting to dynamically construct the object name and invoke it's 'getWeight' method within a loop.

My code is below:

// Importing objects containing 'getWeight' method
const Apple = require('../classses/Apple');
const Pear = require('../classes/Pear);
const Carrot = require('../classes/Carrot);
const Potato = require('../classes/Potato);

const promises = {};
const user = 'userX';  // This is the inputted info, could also equal 'userY'.
const searchableFoods = {
  userX: ['Apple', 'Pear'],
  userY: ['Carrot', 'Potato']
};

for (i = 0; i < searchableFoods[user].length; ++i) {
  promises[searchableFoods[user][i]] = new Promise(function(resolve, reject) {
    // Below line should behave like: Apple.getWeight(arg1, function....
    searchableFoods[user][i].getWeight(arg1, function(response) {
      resolve(response);
    })
  })
}

Unfortunately, I get this error:

[searchableFoods[user][i].getweight] is not a function

I've tried a number of variations but can't make it work. Is it possible to do this?

Upvotes: 0

Views: 35

Answers (3)

Revanth M
Revanth M

Reputation: 113

You're trying to access getWeight as a property of string 'Apple' and not of the actual object Apple that you are importing.

Change the subset array to something like this

const searchableFoods = {
  userX: [Apple, Pear],
  userY: [Carrot, Potato]
};

Which makes the final code to be

const Apple = require('../classses/Apple');
const Pear = require('../classes/Pear);
const Carrot = require('../classes/Carrot);
const Potato = require('../classes/Potato);

const promises = {};
const user = 'userX'  // This is the inputted info, could also equal 'userY'.
const searchableFoods = {
  userX: [Apple, Pear],
  userY: [Carrot, Potato]
};

for (i = 0; i < searchableFoods[user].length; ++i) {
  promises[searchableFoods[user][i]] = new Promise(function(resolve, reject) {
    // Below line should behave like: Apple.getWeight(arg1, function....
    searchableFoods[user][i].getWeight(arg1, function(response) {
      resolve(response);
    })
  })
}

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370809

Require all of those into a single object rather than many standalone variables, and then you can use simple property lookup to get to the appropriate requireed value. Also, forEach will likely result in more readable code, and you can pass the function name alone (resolve) rather than defining an extra anonymous function for the getWeight callback:

const foods = {
  Apple: require('../classses/Apple'),
  Pear: require('../classes/Pear),
  Carrot: require('../classes/Carrot),
  Potato: require('../classes/Potato)
};

// ...

searchableFoods[user].forEach((foodName) => {
  promises[foodName] = new Promise((resolve) => {
    foods[foodName].getWeight(arg1, resolve);
  });
});

Upvotes: 1

Vladimir M.
Vladimir M.

Reputation: 136

Can you define array not using strings? Something like that?

const searchableFoods = {
  userX: [Apple, Pear],
  userY: [Carrot, Potato]
};

Upvotes: 1

Related Questions