0

I have an array that looks like this :

"attributes": [{"id": "5dad5242e7038210842ec59c","value": 3},{"id": "5dbade6a824f3e2244b2870b","value": 6},{"id": "5d7c943a5759f91e187520cc","value": 17}]

Each value in the array corresponds to a schema from where I will fetch that data. Ex : if(value == 1){ fetch data from schemaA}

Based on the data fetched from each schema I will repopulate the array with additional information, so at the end the array would look like this:

"attributes": [{"id": "5dad5242e7038210842ec59c","value": 3, "name": "attributeA"},{"id": "5dbade6a824f3e2244b2870b","value": 6, "name": "attributeF"},{"id": "5d7c943a5759f91e187520cc","value": 17, "name": "attributeQ"}]

So far I have written a function :

exports.fetchAttributes = (attr, callback) => {
    try {
        switch (attr.value) {
            case 3:
                this.fetchAttributeC(attr.id, (err, attributeB) => {
                    callback(err, attributeB);
                });
                break;
            case 6:
                this.fetchAttributeF(attr.id, (err, attributeF) => {
                    callback(err, attributeF);
                });
                break;
            case 7:
                this.fetchAttributeQ(attr.id, (err, attributeQ) => {
                    callback(err, attributeQ);
                });
                break;
            default : console.log("Invalid value");
        }
    } catch(e){
        console.log("Catch in fetchAttributes "+e);
        return callback(e, null);
    }
}

The above function is being called within another function:

exports.functionAttributes = (attributes, callback) => {
    let newAttributes = [];
    attributes.forEach((attr) => {
        this.fetchAttributes(attr, (err, attributeFull) => {
           newAttributes.push(attributeFull);
        })
    }
   //need to pass in callback here, but obviously there is a scope issue
} 

I need this array with newAttributes as I have to pass it to the final callback in async waterfall where this function is. Due to the scope issue newAttributes is always empty. I need help finding a better way to achieve this. So I can finally end up with result array as I have shown above. Any help is greatly appreciated.

P.S : I have tried conditional callbacks, promises but I couldn't make it work as I need to pass parameters in each step. Feel free to point out where I am wrong, or if there is a better method of achieving this, I would be happy to learn.

hushie
  • 417
  • 10
  • 23

1 Answers1

0

I think a promise list would perfectly solve your problem as long as you structured it correctly.

First: Make fetchAttributes return a promise:

return new Promise(function(resolve, reject) {
  ...Your try catch using resolve() and reject()
})

Second: Create the Array of your promises

let fetchList= [];
attributes.forEach((attr) => {
    fetchList.push(...your function)
}

Third: If you don't care whether one fails, make sure to add in a reflection so the promise.all() always completes -> Check this stack post

Finally Once your promise.all() resolves, you can loop through all of the returned values and push them to the newAttributes variable!!!

If you have trouble with it I can provide more info but that should get you started!