0

I want to push a string in an array in a MongoDB document using React/NodeJS/MongoDB,

Here's my code in React

async function toggleLike() {
      try {
        const dataUser = await axios.post(
          `http://localhost:5000/user/${props.auth.user.id}/add/moviesLiked/${props.match.params.id}`);
        console.log("user ", dataUser);
        forceUpdate();
      } catch (error) {
        console.log(error);
      }

Here's my code in NodeJS

router.post("/user/:user/add/moviesLiked/:movie", function(req, res) {
  console.log("in api function add");
  mongo.connect(
    url,
    {
      useNewUrlParser: true,
      useUnifiedTopology: true
    },
    (err, client) => {
      if (err) {
        console.error(err);
        return;
      }
      const db = client.db("ofilms-demo");
      const collection = db.collection("users");
      collection.update(
        { _id: req.params.user },
        { $addToSet: { moviesLiked: req.params.movie } }
      );
      console.log("req params user ", req.params.user);
      console.log("req params movie ", req.params.movie);
      client.close();
    }
  );
});

Here's the model of an user in Mongoose

const UserSchema = new Schema({
  moviesLiked: Array,
  moviesDisliked: Array,
});

All my console.log show the right thing, but I still don't have the data pushed in the array,

Can somebody help me ? Thank you,

2 Answers 2

1

collection.update is asynchronous, so you need to wait for it to finish executing before closing your connection to Mongo and returning a response to the client.

You can wait for the update operation to complete by either passing a call back to the update method or using the async/await javascript feature.

Passing a call back function:

router.post("/user/:user/add/moviesLiked/:movie", function (req, res) {
  mongo.connect(
    url,
    {
      useNewUrlParser: true,
      useUnifiedTopology: true
    },
    (err, client) => {
      if (err) {
        console.error(err);
        return;
      }
      const db = client.db("ofilms-demo");
      const collection = db.collection("users");
      collection.update(
        { _id: req.params.user },
        { $addToSet: { moviesLiked: req.params.movie } },
        function (error, result) { // The callback function
          if (error) {
            // Handle the error and send a respone to the user
          } else {
            // Make use of the result and send a response to the user
          }
          client.close();
        }
      );
    }
  );
});

Using async/await:

// Add the async keyword before declaring the function
router.post("/user/:user/add/moviesLiked/:movie", async function (req, res) {
  mongo.connect(
    url,
    {
      useNewUrlParser: true,
      useUnifiedTopology: true
    },
    (err, client) => {
      if (err) {
        console.error(err);
        return;
      }
      const db = client.db("ofilms-demo");
      const collection = db.collection("users");
      try {
        // Add the await keyword before the update call
        await collection.update(
          { _id: req.params.user },
          { $addToSet: { moviesLiked: req.params.movie } },
        );
        // Send response to your client
      } catch (err) {
        // Handle any possible error
      }
      client.close();
      console.log("req params user ", req.params.user);
      console.log("req params movie ", req.params.movie);
    }
  );
});
Sign up to request clarification or add additional context in comments.

Comments

1

After DB i/o operation is done you should send back the response to your client something like this:

use try-catch to get the error message without crashing the whole node server. Don't forget to send back the response to client otherwise, the client-side will keep waiting for server response until it's timeout reached

Node.js

router.post("/user/:user/add/moviesLiked/:movie", async (req, res) =>{
  console.log("in api function add");

  mongo.connect(
    url,
    {
      useNewUrlParser: true,
      useUnifiedTopology: true
    },
    (err, client) => {
      if (err) {
        console.error(err);
        res.status(500).send({"message":"error occured", err})
        return;
      }
      try{

      const db = client.db("ofilms-demo");
      const collection = db.collection("users");
      const response = await collection.update(
        { _id: req.params.user },
        { $addToSet: { moviesLiked: req.params.movie } }
      );
      console.log("req params user ", req.params.user);
      console.log("req params movie ", req.params.movie);

      //send back the response
       res.status(200).send({response, "message":"your profile is successfully updated."})

      client.close();
    }catch(err){

//check what is the error in your Nodejs console (Not browser console)
  console.log(err) 
 //send back response
  res.status(500).send({"message":"error occured", err})
  }
  );
  }
});

MongoDB is itself schema-less. you don't have to provide schema. if you want to provide your own schema I'd recommend using mongoose. & mongoose arrays

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.