Search code examples
node.jsmongodbmongoosemongoose-schemamern

Update the value of an array by index in document in MongoDB with node.js


I am creating a e-commerce website in react and I am adding a multiple address functionality, but I am new to MongoDB and I have no Idea how do I update a value of an array by it's index, I am taking the details of the address by destructuring the req.body and taking the addressId which is the index of the address array which the user wants to update, I want to update the array address at the position of addressId(0, 1, 2, 3...).

or if I can update the array in anyway by it's index then it would also work for me please help me out.

my current code.

exports.updateAddress = async (req, res, next) => {
  try {
    const { userId, addressId, firstname, lastname, company, phone, address1, address2, city, zipcode, state, defaultAdd } = req.body;
    const result = await User.updateOne({ _id: userId }, {
      address: { // this address needs to be updated by the index.
        firstname: firstname,
        lastname: lastname,
        company: company,
        phone: phone,
        address1: address1,
        address2: address2,
        city: city,
        zipcode: zipcode,
        state: state,
        defaultAdd: defaultAdd
      }
    })
    console.log(result)
    res.status(200).json({
      data: true
    })
  } catch (error) {
    next(error)
  }
}

my user schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
  firstname: {
    type: String,
    required: true
  },
  lastname: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    requried: true
  },
  role: {
    type: String,
    default: 'basic',
    enum: ["basic", "supervisor", "admin"]
  },
  accesstoken: {
    type: String
  },
  address: [ // this is the address array schema 
    {
      addressId: {
        type: Number,
        required: true
      },
      firstname: {
        type: String,
        required: true
      },
      lastname: {
        type: String,
        required: true
      },
      company: {
        type: String,
      },
      phone: {
        type: Number,
        required: true
      },
      address1: {
        type: String,
        required: true
      },
      address2: {
        type: String
      },
      city: {
        type: String,
        required: true
      },
      zipcode: {
        type: Number,
        required: true
      },
      state: {
        type: String,
        required: true
      },
      defaultAdd: {
        type: String
      }
    }
  ]
});

module.exports = mongoose.model('users', UserSchema);

Solution

  • give it a filter of the addressId then it will go there where the addressId:addressId (1, 2, 3...), then just set the values of the keys as you want something like this

    const result = await User.updateOne({ _id: userId, 'address.addressId': addressId }, {
          $set: {
            'address.$.firstname': firstname,
            'address.$.lastname': lastname,
            'address.$.company': company,
            'address.$.phone': phone,
            'address.$.address1': address1,
            'address.$.address2': address2,
            'address.$.city': city,
            'address.$.zipcode': zipcode,
            'address.$.state': state,
            'address.$.defaultAdd': defaultAdd
          }
        })