2

I am creating an app where I want to toggle the default address of a person.
My User Schema contains a field which is an array of delivery addresses which are objects.
One of the fields is isDefault, which is the defaultAddress field I want to toggle from true to false and vice versa.
Specifically, if the user changes their default address, I want to set the rest of the addresses to false and update the one he/she chose to be true

User Schema

const UserSchema = Schema({
 email: {
    type: String,
    required: true,
  },
 deliveryAddresses: [deliverySchema]

Delivery Address Schema

{
      id: {
        type: Schema.Types.ObjectId,
        required: true
      },
      isDefault: {
        type: Boolean,
        required: true,
        default: false,
      },
      name: {
        type: String,
      },
      email: {
        type: String,
      },
      phone: {
        type: String,
      },
     
    }

To do that, what I have done so far is:
Getting the email of the user.
Getting the id of the delivery address from the user that will be toggled to true.

exports.setDefault = (req, res, next) => {
  const email = req.body.email;
  const id = req.body.id;

  User.findOne({ email: email })
    .then((user) => {
      let addresses = [...user.deliveryAddresses];

      addresses.forEach((address) => {
        address.isDefault = false;
      });
    
      const index = addresses.findIndex((address)=> {
          return address.id.toString() === id.toString();
      });

      addresses[index].isDefault = true;
  
      user.deliveryAddresses = addresses;
      return user.save();  
    })
    .then((doc) => {
      res.status(200).json({
        user: doc,
        statusCode: "200",
        msg: "Address updated successfully",
      });
    })

    .catch((err) => {
      res.status(500).json({
        statusCode: 500,
        error: err,
        msg: "Something went wrong",
      });
    });
};

However, after doing all this, on testing my api on postman, it seems to work, no errors. But on checking the database, nothing has changed.
I am at loss as to what I'm doing wrong.

2 Answers 2

2

Mongoose is weird. You need to mark the deliveryAddresses sub-object as modified, otherwise its changes won't be saved.

user.markModified('deliveryAddresses');
user.save();
Sign up to request clarification or add additional context in comments.

1 Comment

I cannot thank you enough mahn. I've spent 2hrs wondering what's wrong with my code
1

From Mongoose FAQs

"Mongoose doesn't create getters/setters for array indexes; without them mongoose never gets notified of the change and so doesn't know to persist the new value. There are two workarounds: MongooseArray#set or Document#markModified()."

Can you try sth like

user.markModified('deliveryAddresses');
user.save();

More on https://mongoosejs.com/docs/faq.html

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.