mongoman
mongoman

Reputation: 69

Mongoose how to push to array

Hi I'm stuck with this problem. I just gotta clear and update my array in mongoose here's my all router code

router.get("/update", (req, res, next) => {
    //update edilcek obje bulunur
    const promise = Dictionary.findByIdAndUpdate(
        "5fece9e86f500741f0b6bba4"
        , { $set: { dict: [] } },
        
        { new: true }
    );
 
    var texts = ["Certain", "Deduce", "Marauders", "Favour"];
 
    promise.then((dictData) => {
        
        texts.forEach(element => {
            translatte(element, { to: 'fr' }).then(res => {
                //i can get values hereby
                console.log("Word: "+element+ " Translate: " + res.text);
                 var metn=element;
                 var cev=res.text;
                 //but not pushing
                dictData.dict.push({ text: metn, translated_text: cev });
            });
            
        });
            //this 2 line pushs data 
        dictData.dict.push({ text: "element2", translated_text: "res.tex2" });
        dictData.dict.push({ text: "element3", translated_text: "res.tex3" });
        dictData.name="3423asd";
        dictData.save().then(()=>{
            console.log("update ");
        }).catch(err=>{
            console.log("save error");
            console.log(err);
        });
    }).catch(err => {
        console.error(err);
    });


    res.render('index', { title: 'Express' });

});


module.exports = router;

In mongo atlas all I can get this

The last 2 push Console log works fine

Word : "ssss" Translate:"sss"

Basicly i cant fill the array. Where is the problem. Thank you

The new error enter image description here

Upvotes: 1

Views: 95

Answers (1)

Abbas Hosseini
Abbas Hosseini

Reputation: 1643

The reason is that your translatte function is asynchronous and it's then block runs after all your synchronous statements are already executed and your DB is already updated.

And the other problem is that you're using finByIdAndUpdate and save methods simultaneously.

You can solve your problem by changing the findByIdAndUpdate to findById and using an async request handler so you can await for all your translatte functions in the for loop to be executed and then update the document and send the response back.

router.get("/update", async (req, res, next) => {
  const dictData = await Dictionary.findById("5fece9e86f500741f0b6bba4").exec();
  dictData.dict = [];
  var texts = ["Certain", "Deduce", "Marauders", "Favour"];
  for (const element of texts) {
    const res = await translatte(element, { to: "fr" });
    var metn = element;
    var cev = res.text;
    dictData.dict.push({ text: metn, translated_text: cev });
  }
  dictData.dict.push({ text: "element2", translated_text: "res.tex2" });
  dictData.dict.push({ text: "element3", translated_text: "res.tex3" });
  dictData.name = "3423asd";
  const result = await dictData.save();
  console.log("updated", result);
  return res.render("index", { title: "Express" });
});

module.exports = router;

Upvotes: 1

Related Questions