0

I have a for loop that creates products in the database and also want that productsarray to be pushed in another collection ,so I want it to store in a temporary array,but before executing the complete for loop the javascript control goes and executes the rest of the code due to which the temporary array is empty. I want something so that the javascript control goes to next statement only after the for loop is executed completely.

for(let i=0;i<productsname.length;i++){
        name=productsname[i]
        cost=productcost[i]
        Product.create({name:name,cost:cost},function(err,product){
            productArray.push(product);
        })
    }
var newOrder={id:count++,dateofdispatch:req.body.date,transport:req.body.transport,amount:req.body.totalcost,product:productArray}
1
  • You may accept one of the answers below. If those not working for you, you may give them feedback. Commented Jun 7, 2020 at 11:18

5 Answers 5

1

What you can do:

First you can create a promise for Product.create

new Promise(function(resolve, reject) { ... });

then you can create an array with your promises and start all by:

Promise.all(promises).then(res => {  })

See: MDN Promise and MDN Promise.all

Try this:

const promises = [];
for (let i=0; i<productsname.length; i++){
    const name = productsname[i];
    const cost = productcost[i];
    promises.push(
        new Promise((resolve, reject) => {
                Product.create({name,cost},(err,product) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(product);
                    }
                }):
        })
    );
}

Promise.all(promises).then(res => {  
    console.info(res);
    // TODO what you want
});

PS: {name:name,cost:cost} short form: {name,cost}

Sign up to request clarification or add additional context in comments.

Comments

0

To handle this you can do something like this:

let numCreated = 0;
for(let i=0;i<productsname.length;i++){
        name=productsname[i]
        cost=productcost[i]
        Product.create({name:name,cost:cost},function(err,product){
            productArray.push(product);
            numCreated++;
            if(numCreated === productsname.length){
              onLoopCompleted(productArray);
            }
        })
    }

function onLoopComplete(productArray){
  var newOrder =  { id: count++, dateofdispatch: req.body.date, transport: req.body.transport, amount: req.body.totalcost, product: productArray }
  // Do what needs to be done here
}

If the library you are using is a promise compliant, then you can look at Promise.all

1 Comment

Thanks,Was a simple solution to implement
0

You need to use an asynchronous design pattern. Promise.all seems to fit exactly your requirement but I don't know if the library you are using for mongodb is Promise compliant.

If your library is not Promise compliant you can implement them by yourself.

let promiseArray;

for(let i=0;i<productsname.length;i++){
    name=productsname[i]
    cost=productcost[i]
    promiseArray.push(new Promise((resolve,reject) => {
        Product.create({name:name,cost:cost},function(err,product) {
            if(err) reject(err);
            else resolve(product);
        })
    }));
}

Promise.all(promiseArray).then(yourResultArray => {
    // rest of your program goes here
})

Comments

0

if you want to create a temporary Array just do it

const procductArray = [];

your FOR loop

for(let i=0;i<productsname.length;i++){
        const newProduct = {
        name=productsname[i]
        cost=productcost[i]
        }
      Product.create({name:newProduct.name,cost:newProduct.cost},function(err,product){
            productArray.push(newProduct);
        })
    }

3 Comments

I'm afraid that this is not the question. The problem is, that productArray.push is executed in a callback (later) --> Array is not filled after the for loop (where the array should be used)
what is productArray? It will contain all products okay?
I'm afraid that you misunderstood the question. It's a timing problem. Async execution problem.
0

You should synchronize your code either with Promise or async/await.

Check code below for await example :

(async function () {
  for (let i = 0; i < productsname.length; i++) {
    name = productsname[i];
    cost = productcost[i];
    await Product.create({ name: name, cost: cost }, function (err, product) {
      productArray.push(product);
    });
  }
  var newOrder = await {
    id: count++,
    dateofdispatch: req.body.date,
    transport: req.body.transport,
    amount: req.body.totalcost,
    product: productArray,
  };
  // do another thing and dont forget to use await

})();

await expression can only be used in async function. Above code create an async function and immediately calls it. It is called an IIFE (immediately invoked function expression). You may also create an async function and use somewhere else :

async function createProductArray () {
  for (let i = 0; i < productsname.length; i++) {
    name = productsname[i];
    cost = productcost[i];
    await Product.create({ name: name, cost: cost }, function (err, product) {
      productArray.push(product);
    });
  }
  var newOrder = await {
    id: count++,
    dateofdispatch: req.body.date,
    transport: req.body.transport,
    amount: req.body.totalcost,
    product: productArray,
  };
  // do another thing and dont forget to use await

};

// somewhere in your code
createProductArray()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.