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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.