Search code examples
node.jsarraysmongodbdiscord.js

how to add items into array in node js with mongodb?


i'm writing a bot that is able to randomly pick out a card from a .json file i have, and should add it into the user's card inventory. each card comes with it's own unique code. if the user had the card previously, it will add 1 to the quantity. else, it should create a data of the randomised card under the cards array.

so i tried to search up the code from the user's inventory first, and then if it doesn't exist, to populate it.

however, even though there are no errors returned, the array is still empty on mongodb everytime i use the command to get a card.

const { idolname, group, era, rarity, code, image, qty } = cards ?? {};

const newCard = { "cards.code": `${code}` };
         const updateInv = { $inc: { "cards.$.qty": 1 }};

        let searchInv = await UserProfile.findOne({newCard});

        if (!searchInv) {
            UserProfile.updateOne({ $push: { "cards": { "cards.$.idolname": `${idolname}`, "cards.$.era": `${era}`, "cards.$.groupp": `${group}`, "cards.$.rarity": `${rarity}`, "cards.$.code": `${code}`, "cards.$.qty": '1'}}});
        } else {
            UserProfile.updateOne(newCard, updateInv);
        }

below is how the schema is set

const { time } = require('discord.js');
const { Schema, model } = require('mongoose');

const userProfileSchema = new Schema({
    userName: {
        type: String,
    },
    userId: {
        type: String,
        required: true,
    },
    balance: {
        type: Number,
        default: 0,
    },
    lastDailyCollected: {
        type: Date,
    },
    lastDrop: {
        type: Date,
    },
    cards: [ {
        idolname: String,
        group: String,
        era: String,
        rarity: Number,
        code: String,
        image: String,
        qty: Number,
        }],
},
{ timestamps: true }
);

module.exports = model('UserProfile', userProfileSchema);

i'm not sure if it's the fact that i'm trying to add the name of the randomised card that is messing things up here - since i am not simply pushing a set value.

or perhaps the problem is with the card database being on local .json and not uploaded into mongodb?

please help me out, i am so confused - please point me in the right direction.

i am very new to coding and tried to search up solutions but i can't seem to get it either way.


Solution

  • Here is an example of a straightforward way to firstly check for the user and if they have the correct card then add 1 to the qty property. But if they don't have the card the result will be null so you can then add a new card to the cards array. There are more complex ways where this can be done in one query using aggregation $set stages but this way is easier for you to follow:

    try{
       // Find the user but only match if they already have cards.code === code
       // If they exist then just increment the qty using $ positional operator 
       const incUser = await UserProfile.findOneAndUpdate(
          {
             userId: interaction.user.id,
             "cards.code": code
          }, 
          { $inc: { "cards.$.qty": 1 } }, 
          {new: true}
       );
       // If no matches were found it means we need to push a new card to this user
       if(!incUser){ 
          const pushUser = await UserProfile.findOneAndUpdate(
             { userId: interaction.user.id }, 
             { 
                $push: { 
                   cards: { 
                      idolname: idolname, 
                      era: era, 
                      group: group, 
                      rarity: rarity, 
                      code: code, 
                      qty: 1
                   }
                }
             }, 
             {new: true}
          );
       }
       return res.status(201).json({
          message: 'User updated'
       })
    }catch(err){
       console.log(err);
       return res.status(500).json({
          message: 'Error on server'
       })
    }