skip to Main Content

I will try my best to explain the situation.

Let say there are 4 patch requests made to /inventorys/users/:inventoryId. with the data from body.

These are the 4 requests with body data.

REQUEST1 => { users: 65ef2d09ef674c1e1a3632e5 }

REQUEST2 => { users: 65ef2d09ef674c1e1a3632e5 }

REQUEST3 => { users: 65ef2d11ef674c1e1a3632e9 }

REQUEST4 => { users: 65ef2d11ef674c1e1a3632e9 }

In my database I want to add or remove user from the inventory.

Here is the code

router.patch("/inventorys/users/:inventoryId", auth, async (req, res) => {  
  try {
    //check if inventory exist and 
    const inventory = await Inventory.findOne({
      _id: req.params.inventoryId
    });

    if (!inventory) {
      return res.status(404).send({ error: "Inventory not found" });
    }

    // check if user exist in the data base.
    const newUserOrOldUser = await User.findOne({
      _id: req.body.users,
    });


    // Check if user already exist users array
    const userIndex = inventory.users.findIndex((userId) =>
      userId.equals(req.body.users)
    );

    // new user
    if (userIndex === -1) {
      await Inventory.updateOne(
        { _id: inventory._id },
        { $push: { users: req.body.users } }
      );
      console.log("add user", req.body.users, req.user._id);
    } else {
      await Inventory.updateOne(
        { _id: inventory._id },
        { $pull: { users: req.body.users } }
      );
      console.log("remove user", req.body.users);
    }
    return res.status(200).send(inventory);
  } catch (err) {
    if (err) {
      res.status(400).send({ error: err.message });
    }
  }
});

Before making those 4 request at top. I delete all users from the inventory array manually.

Here is the console that comes out when i made those request

remove user 65ef2d09ef674c1e1a3632e5
add user 65ef2d09ef674c1e1a3632e5
add user 65ef2d11ef674c1e1a3632e9
remove user 65ef2d11ef674c1e1a3632e9

As you can see from the first request It saying the user is removed. but the res.send is actually sending me the added data.

For the second request It saying added user but the users array is now empty.

For the Third request This is the weird part. Its saying add user add user 65ef2d11ef674c1e1a3632e9 but the data send back is with 65ef2d09ef674c1e1a3632e5 in the user array. So idk how the user from last request is added in this request.

Now for the 4th request. Its saying remove user 65ef2d11ef674c1e1a3632e9 but now its adding the user 65ef2d11ef674c1e1a3632e9 because this user is not in the array yet.

So at the end of 4 request the users array got 2 users. Its should be empty

2

Answers


  1. This might be due to the stale state of your inventory variable. You are fetching the inventory at the start of the request, and never updating it. You do use the inventory variable across various conditions and DB operations, but you aren’t updating it whatsoever.

    You should do one of the following:

    1. Update the inventory variable locally whenever you make a change
    2. Fetch the updated state of the Inventory before you send the response, and update the inventory variable.

    Let me know if this helps!

    Login or Signup to reply.
  2. In this part of your code:

    const userIndex = inventory.users.findIndex((userId) =>
       userId.equals(req.body.users)
    );
    

    You are using a non standard equals() function so your code could well be erroring here. By that I mean you expect to get a -1 when the inventory.users is an empty array or the value is not in the array but it is likely that userIndex is not what you expect.

    Here is some code that could better achieve your desired outcome

    router.patch("/inventorys/users/:inventoryId", auth, async (req, res) => {
        try {
            // 1. check if user exist in the database.
            const existingUser = await User.findOne({
                _id: req.body.users,
            });
            // 1.1 Return error as no user exits
            if (!existingUser) {
                return res.status(404).send({ error: "User not found" });
            }
            
            // 2. check if inventory exist 
            const inventory = await Inventory.findOne({
                _id: req.params.inventoryId
            });
            // 2.1 Return error as no inventory exits
            if (!inventory) {
                return res.status(404).send({ error: "Inventory not found" });
            }
            
            //
            // At this stage we know that we have an existingUser && inventory otherwise it would have returned
            //
            
            // 3. Check if inventory exits with this user
            const inventoryWithUser = await Inventory.findOne({
                _id: req.params.inventoryId,
                users: req.body.users
            })
     
            if (!inventoryWithUser) {
                // 3.1.a  We now know that we have an existingUser && inventory but the user IS NOT in this inventory
                // So we can push the existingUser to the inventory.users array we got earlier
                inventory.users.push(req.body.users);
                await inventory.save();
                console.log("User ADDED to inventory", req.body.users, req.user._id);
                return res.status(200).send(inventory);
            }else{
                // 3.1.b  We now know that we have an existingUser && inventory AND the user IS in the inventory
                // So we can pull it from the inventoryWithUser.users array
                inventoryWithUser.users.pull(req.body.users);
                await inventoryWithUser.save();
                console.log("User REMOVED from inventory", req.body.users, req.user._id);
                return res.status(200).send(inventoryWithUser);
            }
        } catch (err) {
            if (err) {
                res.status(400).send({ error: err.message });
            }
        }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search