Search code examples
javascriptnode.jsmongodbmongoosemongoose-schema

Mongodb : Adding new data object into an array of object with node.js mongoose


I want to add a new data object inside of a nested document in MongoDB. this is what my schema look like :

const transactionSchema = new Schema({
  transactionType: {type: String, require: true, trim: true},
  senderWallet: {type: String, require: true, trim: true},
  recipientWallet: {type: String, require: true, trim: true},
  amount: {type: Number, require: true, trim: true},
  createdAt: {type: Date, require: true},
});

const walletHoldShema = new Schema({
  balance: {type: Number},
  transaction:[transactionSchema]

});


const walletSchema = new Schema({
  createdAt: {type: Date, require: true},
  userId: {type: String, require: true, trim: true},
  walletAdrress: {type: String},
  usdWallet: [walletHoldShema],

})

const Wallets = mongoose.model('wallet', walletSchema);

module.exports = Wallets

This is what my data look like right now

wallet: {
                "_id": "60ca5e8e2c57463733b65f89",
                "usdWallet": [
                    {
                        "_id": "60ca5ede2c57463733b65f8a",
                        "balance": 0,
                        "transaction": []
                    }
                ],
                "createdAt": "2021-06-16T20:28:14.589Z",
                "userId": "fb0df5c9a9eb",
                "walletAdrress": "fb0df5c9a9eb",
                "__v": 0
            }

I have tried different solution like this one which I followed via stack :

const _id = req.params._id;  

            const transactionInput = {
                transactionType: 'input',
                senderWallet: req.body.sender,
                recipientWallet: req.body.recipient,
                amount: req.body.amount,
                createdAt: Date.now(),
            };

            walletSchema.findOneAndUpdate({_id: _id}, {$push: {transaction: transactionInput}}, { new: true }, function(err, data){
                if (err) {
                    res.send(err);
                } else {
                    res.send(transactionInput);
                }
            });

// calling router 
router.patch('/v1/sendUSD/', wallet.sendDollar

But I am getting this in my DB after my router is called :

"wallet": [
              {
                "_id": "60ca5e8e2c57463733b65f89",
                "usdWallet": [
                    {
                        "_id": "60ca5ede2c57463733b65f8a",
                        "balance": 0,
                        "transaction": []
                    }
                ],
                "createdAt": "2021-06-16T20:28:14.589Z",
                "userId": "fb0df5c9a9eb",
                "walletAdrress": "fb0df5c9a9eb",
                "__v": 0
            },

            {
                "_id": "60ca5e8e2c5746373",
                "usdWallet": [
                    {
                        "_id": "60ca5ede2c57463733b65f8a",
                        "transaction": 
                        [
                            {
                              "transactionType": "input",
                              "senderWallet": "fcdhjgknsdfihber",
                              "recipientWallet": "mbindu",
                              "amount": "50.0",
                              "createdAt": 1623881009306
                            }
                        ]
                    }
                ],
           
            },


]

But what I want is this :

wallet: [
              {
                "_id": "60ca5e8e2c57463733b65f89",
                "usdWallet": [
                    {
                        "_id": "60ca5ede2c57463733b65f8a",
                        "balance": 0,
                        "transaction":
                         [
                            {
                              "transactionType": "in",
                              "senderWallet": "fcdhjgknsdfihber",
                              "recipientWallet": "mbindu",
                              "amount": "50.0",
                              "createdAt": 1623881009306
                            },
                            {
                              "transactionType": "out",
                              "senderWallet": "fcdhjgknsdfihber",
                              "recipientWallet": "mbindu",
                              "amount": "50.0",
                              "createdAt": 1623881009306
                            },

                        ]
                    }
                ],
                "createdAt": "2021-06-16T20:28:14.589Z",
                "userId": "fb0df5c9a9eb",
                "walletAdrress": "fb0df5c9a9eb",
                "__v": 0
            },
]

Solution

  • having an array inside an array is always a bad idea. that said, you can push transaction into usdWallet through:

    walletSchema.findOneAndUpdate({ _id: _id }, { $push: { "usdWallet.$.transaction": transactionInput }}, { new: true }, function(err, data) {
      if (err) {
        res.send(err); 
      } else {
          res.send(transactionInput);
      }
    });