I have an array of objects that is defined in mongoose schema as
blacklistGroup: {
userId: { type: String },
username: { type: String }
}
I can't figure out why it won't POST into mongodb.
I have a console.log that shows that it represents it's schema, but it never appears in mongodb? What am I doing wrong?
console.output
req.body.blacklistGroup
[ { userId: '5e2350c7f88cfb331c4f67de', username: 'artist1' },
{ userId: '5e20c5a139a92512cc7df63c', username: 'artist' } ]
[object Object]
app.js
app.post("/api/listings", checkAuth, (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const post = new Post({
blacklistGroup: req.body.blacklistGroup,
});
//saves to database with mongoose
post.save().then(result => {
console.log(result);
res.status(201).json({
message: "Auction listing created successfully!",
postId: result._id
});
});
});
You can store all user at once. use mongoose insertMany
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,(req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
(async function(){
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
})();
});
Or you can use
const Post = require('post'); //mongoose schema
app.post("/api/listings", checkAuth,async (req, res, next) => {
console.log("req.body.blacklistGroup");
console.log(req.body.blacklistGroup);
let blacklistGroup = req.body.blacklistGroup;
console.log("req.body.blacklistGroup");
const blacklistGroup = req.body.blacklistGroup;
await Post.insertMany(blacklistGroup);
res.status(200).send('Ok');
});
For More Here
You don't have an array of objects (or at least you don't want one), you have an object with two properties; userId and username. MongoDB is expecting JSON and it looks like you're trying to send it an array containing that object.
Try this:
let blacklistGroup = req.body.blacklistGroup[0];
To process an array of objects passed as req.body.blacklistGroup, you will have to iterate over it, define a new Post for each object and then send it. I think part of the confusion here is that your Schema is called blacklistGroup but it doesn't refer to a group, it refers to one entry.
const dbCalls = blacklistGroup.map(userObject => {
const post = new Post({
blacklistGroup: {
userId: userObject.userId,
username: userObject.username
});
return new Promise((resolve, reject) => {
post.save.then(() => {
resolve();
})
.catch(err => {
reject(err);
})
})
});
Promise.all(dbCalls).then(() => {
res.status(201).json({message: "Auction listings created successfully!"})
})
.catch(err => {
res.status(500).json({error: err})
});
Related
committeeHead is a reference in collection users. I want to populate this id to get the specific data.
tried using Promise.all but I don't completely understand it and it isn't working for me.
const getAllCommittees = async (req, res, next) => {
try {
const committees = await db.collection("committees").get();
const committeesArray = [];
committees.forEach((doc) => {
committeesArray.push({ id: doc.id, ...doc.data() });
});
const committeesWithUsers = await Promise.all(
committeesArray.map((committee) => {
const user = db.collection("users").doc(committee.committeeHead).get();
return {
committee,
user,
};
})
);
res.json(committeesWithUsers);
} catch (err) {
console.log(err);
next(err);
}
};
I'm getting (throw new error_1.MongoInvalidArgumentError('Update document requires atomic operators'); )
this type of error
Here is the full code for put endpoint:
app.put('/todo/:id', async (req, res) =>
{
const id = req.params.id; const data = req.body;
console.log(data);
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updateDoc = { $set: { name: data.name, message: data.message, }, };
const result = await dataCollections.updateOne(filter, options, updateDoc);
res.send(result);
});
You are sending the parameters in the wrong order, update document comes before options, try this:
const result = await dataCollections.updateOne(filter, updateDoc, options);
I have this collection Cart (cart schema) to delete and it is referenced with 2 other schemes, Meal and Customer (owner user, its schema is: User Schema).
How can I delete the cart by passing as req.params.id the user's id from the HTTP request?
Cart Schema
const mongoose = require('mongoose');
const idValidator = require('mongoose-id-validator');
const Schema = mongoose.Schema;
const cartItemSchema = new Schema ({
quantity: { type: Number, required: true },
itemId: { type: mongoose.Types.ObjectId, required: true, ref: 'Meal' }
});
const cartSchema = new Schema ({
cartItems : [
cartItemSchema
],
customer: { type: mongoose.Types.ObjectId, required: true, ref: 'User'}
});
cartSchema.plugin(idValidator);
module.exports = mongoose.model('Cart', cartSchema);
I created a function to delete the document, but it doesn't work, it returns the message: 'Deleted cart.', but isn't true, the document remains in collection.
const deleteCartByUserId = async (req, res, next) => {
const userId = req.params.uid;
let cart;
try {
cart = await Cart.find({ customer: userId });
} catch(err) {
const error = new HttpError('Something went wrong, could not delete cart.', 500);
return next(error);
}
if(!cart) {
const error = new HttpError('Could not find cart for this user id.', 404);
return next(error);
}
try {
Cart.deleteOne({ customer: userId });
} catch(err) {
console.log(err);
const error = new HttpError('Something went wrong, could not delete cart.', 500);
return next(error);
}
res.status(200).json({ message: 'Deleted cart.' });
};
So the porblem was that you missed an await before delete one function call.
Also I've changed some of youre code to make it cleaner:
const functionHandler = fn =>
(req, res, next) =>
Promise
.resolve(fn(req, res, next))
.catch(next);
const deleteCartByUserId = functionHandler(async (req, res) => {
const { params: { uid: userId } } = req;
const cart = await Cart.findOneAndDelete({ customer: userId })
if(!cart) {
throw new HttpError('Could not find cart for this user id.', 404);
}
res.status(200).json({ message: 'Deleted cart.' });
});
In your error handler middleware you can check for error type and if it's not HttpError use internal server error.
I am a frontend developer. A colleague has kindly built me a MongoDB/Cosmos database in Azure and allowed me to retrieve a single record into my frontend. He has since gone on holiday with no cover.
(I am confused what type of database it is, since it says Azure Cosmos DB in Azure portal, but all the code in my server.js file refers to a MongoDB.) Server.js:
const express = require('express');
const app = express();
const url = 'mongodb://blah.azure.com';
app.use(express.static('static'));
const mongoClient = require('mongodb').MongoClient
let db;
app.listen(process.env.PORT || 3000, async () => {
console.log('App listening on port 3000!')
const connect = await mongoClient.connect(url)
db = connect.db('ideas');
});
app.get('/api/ideas/:name', async (req, res) => {
return res.json(await db.collection('container1').findOne({key: req.params.name}));
});
I want to retrieve all documents in this database. They each have an ID. But my colleague seems to have defined an API by name. From the MongoDB docs I can use the command find({}) instead of findOne({key: req.params.name}) to return all records, but this does not work (i.e. I get no output to the console). I presume this is because of the '/api/ideas/:name'.
I have also tried:
db.open(function(err, db){
var collection = db.collection("container1");
collection.find().toArray(function(err2, docs){
console.log('retrieved:');
console.log(docs);
})
})
but i get an error that tells me I can't retrieve the property "open" of undefined.
Can anyone help me either: (1) work out how to change the API in Azure, or (2) rewrite this code to retrieve all records? I will also need to edit and insert records. Thanks
If you want to retrive data from Mongo DB in nodejs espresso application, I suggest you use the package mongoose.
For example
Create mongo.js file to add connection details
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const accountName= 'testmongo05',
const databaseName= 'test',
const key= encodeURIComponent(''),
const port: 10255
const mongoUri = `mongodb://${env.accountName}:${key}#${accountName}.documents.azure.com:${port}/${databaseName}?ssl=true`;
function connect() {
mongoose.set('debug', true);
return mongoose.connect(mongoUri, {
useFindAndModify : false,
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true
});
}
module.exports = {
connect,
mongoose
};
Define models
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
userId: {
type: String,
required: true,
unique: true
},
name: String,
saying: String
},
{
collection: 'Users'
}
);
const User = mongoose.model('User', userSchema);
module.exports = User;
CURD operations
const express = require('express');
const bodyParser = require('body-parser');
const User = require('./module/user');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
require('./mongo').connect().catch(error => console.log(error));
//list users
app.get('api/users', async (req, res) => {
const docquery = User.find({});
await docquery
.exec()
.then(users => {
res.status(200).json(users);
})
.catch(error => {
res.status(500).send(error);
});
});
// get user by userId
app.get('/api/user/:uid', async (req, res) => {
const docquery =User.findOne({userId:req.params.uid })
await docquery
.exec()
.then(user => {
if (!checkFound(res, user)) return;
res.status(200).json(user);
})
.catch(error => {
res.status(500).send(error);
});
});
// create
app.post('/api/user', async (req, res) => {
const originalUser= { userId: req.body.userId, name: req.body.name, saying: req.body.saying };
const user = new User(originalUser);
await user.save(error => {
if (checkServerError(res, error)) return;
res.status(201).json('User created successfully!');
console.log('User created successfully!');
});
});
//update user by userId
app.put('/api/user/:uid', async (req, res) => {
const docquery =User.findOneAndUpdate({userId: req.params.uid}, req.body)
await docquery.exec()
.then((user) =>{
if (!checkFound(res, user)) return;
res.status(200).json("User update successfully");
console.log('User update successfully!');
})
.catch(error =>{
res.status(500).send(error);
})
});
//delete user by userId
app.delete('/api/user/:uid', async (req, res) => {
const docquery = User.findOneAndRemove({userId: req.params.uid })
await docquery.exec()
.then(user =>{
if (!checkFound(res, user)) return;
res.status(200).json("user deleted successfully!");
console.log('user deleted successfully!');
})
.catch(error =>{
res.status(500).send(error);
})
});
function checkServerError(res, error) {
if (error) {
res.status(500).send(error);
return error;
}
}
function checkFound(res, user) {
if (!user) {
res.status(404).send('user not found.');
return;
}
return user;
}
Test
a. Create user
b. get user
c. List Users
d. Update User
e delete user
I developed my node rest api as usual but this time it is showing some invalid error in controller.js file. The mongoose is not getting required. When I hit the API in postman, it gives the error as :
{
"error": {
"message": "Tweets is not a constructor"
}
}
I even updated my packages for the same, but nothing seems to work. Here is the snippet of my controller for tweets.js:
const mongoose = require('mongoose');
const Tweets = require('../models/tweets');
exports.get_all_tweets = (req, res, next) => {
Tweets.find()
.exec()
.then(docs => {
console.log(docs);
res.status(200).json(docs);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}
exports.create_tweets = (req, res, next) => {
const tweetbody = req.body;
tweetbody._id = mongoose.Types.ObjectId();
const tweet = new Tweets(tweetbody);
tweet
.save()
.then(docs => {
console.log(docs, 'Tweets');
res.status(200).json(docs);
})
.catch(err => {
console.log(err, 'error found');
res.status(500).json({
error:err
});
});
The first mongoose line is appearing blank as shown in the screenshot:
mongoose
Model for tweets.js:
const mongoose = require('mongoose');
const tweetSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
time: { type: String},
count: { type: Number}
});
module.export = mongoose.model('Tweets', tweetSchema);
please check all path and add new keyword before schema initializing
Model for tweets.js:
const tweetSchema = new mongoose.Schema({
Try this using async/await
exports.get_all_tweets = async (req, res, next) => {
const result = await Tweets.find()
res.status(200).json(result);
}
module.exports with a 's' at the end :)