Home > Mobile >  Mongoose document _id is null, so when I try to save I get MongooseError: document must have and id
Mongoose document _id is null, so when I try to save I get MongooseError: document must have and id

Time:06-23

I'm making a discord bot to scrape prices from Amazon. Im using a mongoDB database to store links users give to the bot to track the price of the item the link leads to.

My issue is when I run my code and use the add command, my console reads...

Starting...
Online! Logged in as Amazon Price Tracker#6927
Connected to Database
null
MongooseError: document must have an _id before saving
    at C:\Users\logic\Documents\Disc Bot\node_modules\mongoose\lib\model.js:291:18
    at processTicksAndRejections (node:internal/process/task_queues:78:11)
Disconnected from Database

I've read the doc's and my understanding is mongoose generates a unique id automatically. I am aware that you can override this my defining an id in your schema, but I haven't done this so I don't know why console.log(a) prints null, and the .save() errors out.

My add.js file

//add function using mongoose for mongodb
const { SlashCommandBuilder } = require("@discordjs/builders");

const mongoose = require("mongoose");
const { MongoDBurl } = require("../config.json");
const Link = require("../Schemas/Link.js");

module.exports = {
    //Build the slash command
    data: new SlashCommandBuilder()
    .setName("add")
    .setDescription("add a url to watch list")
    .addStringOption(option =>
        option.setName("url")
            .setDescription("url to add to watch list")
            .setRequired(true),
        ),

    //Function that runs when the command is used
    async execute (interaction) {
        const URL = interaction.options.getString("url");
        const user = interaction.user.username;

        await interaction.reply(`On it! Adding ${URL} to your watch list`)

        //Connect to the database, throws an error if it can't connect
        await mongoose.connect(MongoDBurl)
            .then( () => console.log("Connected to Database"))
            .catch(err => console.log(err));

        //Check if the link is already in the database
        var exists = await Link.exists({ link: URL}).exec()
                    .catch(err => console.log(err))

        if (exists) {
            console.log("This Document Already Exists")
            interaction.editReply(`Oops! That link is already in my database.`)
        } else {
            //If the link dosen't exist, create a document and save it to the database
            var newLink = new Link({ user: user }, { link: URL }, { price: "N/A" })
            // Debuging variable
            var a = newLink.id;
            console.log(a)

            await newLink.save()
                .then( () => {
                    console.log("Document Saved")
                    interaction.editReply(`All done! I have saved ${URL} to your watch list.`)
                })
                .catch(err => {
                    console.log(err)
                    interaction.editReply("Oops! Something went wrong, I wasen't able to save this link.")
                })
        }

        //Close the connection when we finish
        await mongoose.connection.close()
            .then( () => console.log("Disconnected from Database"))
    }
};

My Link.js file

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

const LinkSchema = new Schema({
    user: {
        type: String,
        requiered: true
    },
    link: {
        type: String,
        requiered: true
    },
    price: {
        type: String,
        requiered: true
    },
})

module.exports = mongoose.model("Link", LinkSchema);

CodePudding user response:

So I found my issue. I changed this line

var newLink = new Link({ user: user }, { link: URL }, { price: "N/A" })

To

const newLink = new Link({ user: user, link: URL, price: "N/A" });

I don't know why this fixed it, I don't think its because I changed var -> const, and looking at the documentation I thought the first line was the correct way to do this

The line I originally used from the documentation

Tank.updateOne({ size: 'large' }, { name: 'T-90' }, function(err, res) {
  // Updated at most one doc, `res.nModified` contains the number
  // of docs that MongoDB updated
});

Is this an error in the documentation? or a possible bug? either way the issue is now resolved.

CodePudding user response:

When creating a new modal, the options must be within the same pair of curly braces, however when updating, its separate since you are changing multiple elements.

That's why the error was occurring. You have already shared a working piece of code so I'm guessing you no longer need one.

  • Related