Getting started with express - node.js

I am just getting started learning node.js and express, so forgive me if my question uses the wrong terminology. Hey, gotta start somewhere I guess. So I am following an online tutorial and it aint doing what its supposed to do. (I've got soapui and postman installed, also just learning the ropes) So to the code:
// Defined store route
gameRoutes.route('/add').post(function(req, res) {
let game = new Game(req.body);
game.save()
.then(game => {
res.status(200).json({
'game': 'CoGamein added successfully'
});
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
Tried using the insert code widget but failed miserably, sorry! Anyway what's happening is the data is added to the database but the res.status(200).json({'game': 'CoGamein added successfully'}); is not firing, and VScode gives me a vague error that let game = new Game(req.body); data is not read! Any ideas whats going on?
// Game.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define collection and schema for Games
let Game = new Schema({
name: {
type: String
},
price: {
type: Number
}
},{
collection: 'games'
});
module.exports = mongoose.model('Game', Game);

Try this
gameRoutes.route('/add').post(function (req, res) {
let game = new Game(req.body);
game.save()
.then(game => {
res.send({
game: 'CoGamein added successfully'
});
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
200 is the default success status. You don't need to mention that.

Related

Mongoose document _id is null, so when I try to save I get MongooseError: document must have and id before saving

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);
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.
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.

How can I sort and limit with Mongoose

I made an review app with Express and Mongoose. I have an review model like below:
var mongoose = require('mongoose');
var ReviewSchema = mongoose.Schema({
title: String,
description: String,
rating: Number
}, {
timestamps: true
}
);
module.exports = mongoose.model('Review', ReviewSchema);
In my controller I just get all reviews list as below. But now I want to get a list with 10 recently reviews & sort by (orderby timestamps). How can I do it with mongoose? Please help me! I am a newbie with NodeJS and Mongodb.
exports.findAll = function(req, res) {
console.log("Fetching Review...")
// Retrieve and return all reviews from the database.
Review.find(function(err, reviews){
if(err) {
console.log(err);
res.status(500).send({message: "Some error occurred while retrieving Review."});
} else {
res.send(reviews);
}
});
};
Thanks you so much
This should work for you:
Review.find()
.sort({_id: -1})
.limit(10)
.then(reviews => {
console.log(reviews)
});
you can try like this :
Review.find({}, function(err,reviews){}).sort({_id: -1}).limit(10);

Nodejs Duplicate Fields

I'm using a POST route to post data on a user's progress. I'm looking for a way to check if theres duplicate fields when posting, so I don't post multiple results
My route:
api.post('/progress', (req, res) => {
let progress = new Progress();
progress.user_id = req.body.user_id;
progress.level = req.body.level;
progress.save(function (err) {
if (err) {
res.send(err);
}
res.json({
message: 'progress saved!'
});
});
});
My Model
import mongoose from 'mongoose';
let Schema = mongoose.Schema;
let progressSchema = new Schema({
user_id: String,
level: String,
});
var levels = mongoose.model('Progress', progressSchema);
module.exports = mongoose.model('Progress', progressSchema);
Are you using MongoDB? If so, you can use mongoose module and add
unique: true,
to the field's attributes in your Progress schema. Check out the docs. Hope this helps.

Mongoose save() not being processed

Pardon the noob question, but can anyone spot what am I doing wrong here? For some reason it looks like it does not go through the save() hook, as nothing is printed to the console...
router.post('/users', (req, res, err) => {
var user = new User(req.body);
user.save().then(function(user) {
console.log('user save()');
})
.catch((err) => {
res.send(err);
});
});
When I'm printing to the console the user var, before the save(), I get to see the right data.
Thanks.
EDIT: Resolved.
I've added the auto flag to _id in my schema, as the error was that no _id was provided/generated at insert() time.
_id: {
type: Schema.Types.ObjectId,
auto: true,
},

Create subsubdocs in Mongoose with Nested Schema

I have a User Schema that includes nested Schemas - overall three layers deep. I have no problem adding to Polls, but cannot add Inputs for the life of me. I have tried to get a user then handle the data like regular json (such as getting the index of the polls array and then pushing to the nested input array). I have tried creating a new input and pushing it to the inputs array.
The following code works perfectly for creating a new poll on a given user:
const poll = user.polls.create({});
user.polls.push(poll);
user.save(function(err, data) {
//more stuff here
})
However, when I try the same method on polls, I cannot save to the DB.
const poll = user.polls.id(<some _id>);
const input = poll.create({}); // or user.polls.id(<some _id>).create({});
poll.inputs.push(input);
I have gone back and forth and tried several things and cannot seem to get this to work given my current data structure. I have read several posts on SO as well as other online sources but most give examples for the first embedded subdoc, not the subdoc of the subdoc. Any help you can provide would be greatly appreciated. Thanks. I'm thinking of scrapping Mongoose on this project and just using the mongodb package for clearer control over what is going on with my data.
Here's my current code:
From User.js
const InputSchema = new Schema({
[ALL SORTS OF VARIOUS DATA HERE]
});
const PollSchema = new Schema({
inputs: [InputSchema],
});
const UserSchema = new Schema({
polls: [PollSchema]
});
module.exports = mongoose.model('User', UserSchema);
From controllers.js
const User = require('../models/User');
router.post('/polls/inputs/add/:creatorId', function(req, res) {
let title = req.body.option.title,
order = req.body.option.order,
voters= [];
User.findOne({ creatorId: req.params.creatorId })
.then(user => {
const input = {order, title, voters};
user.polls.id(req.body.pollId).inputs.push(input);
user.save(function(err, data) {
if (err) {
res.statusCode = 500;
return res.json({ title: 'Save Error', message: err });
}
console.log('Success!');
res.json({ input: input });
});
}).catch(err => {
res.statusCode = 500;
return res.json({ title: 'DB Error', message: err });
});;
});
Mongoose isn't able to track changes in subobjects like this, so the field must be marked explicitely as needing to be updated like so:
user.markModified('polls')

Resources