How to save multiple data on mongoose - mongodb

Current code can save single data. I have multiple data at incoming request. How can i save the multiple data to mongodb? As you can see in the image there are 3 different objects.
Orders route
router.route("/api/orders").post((req, res) => {
const body = req.body;
console.log(body);
const orderid = req.body.id;
const ordername = req.bodyname;
const orderdescription = req.bodydescription;
const orderquantity = req.bodyquantity;
const ordertotalprice = req.bodytotalPrice;
const newOrder = new Orders({
orderid,
ordername,
orderdescription,
orderquantity,
ordertotalprice
});
newOrder
.save()
.then(() => {
console.log("Order Added!");
res.status(200).json("Order Added!");
})
.catch(err => res.status(400).json("Error: " + err));
});
module.exports = router;

Your request body is an array of objects.
You can use Model.insertMany() method to insert multiple documents.
Before using insertMany be sure, you convert the objects in request body to the mongoose model object correctly. Here I used javascript map method to show a sample, you may need to change that transformation.
router.route("/api/orders").post((req, res) => {
const body = req.body;
console.log(body);
let items = req.body.map(item => {
return {
orderid: item.id,
ordername: item.name,
orderdescription: item.description,
orderquantity: item.quantity,
ordertotalprice: item.totalPrice
};
});
Orders.insertMany(items)
.then(() => {
console.log("Orders Added!");
res.status(200).json("Order Added!");
})
.catch(err => res.status(400).json("Error: " + err));
});
module.exports = router;

Related

Error: TypeError: user.insertOne is not a function using mongoose

I'm having difficulty creating the routes to send to MongoDB.
When I return user, it returns the full database. This goes for using User or 'user'.
User is a model
let User = require('../models/user.model');
User.findById(req.params.id)
.then(user => {
if (!user)
res.status(404).send("data is not found");
else
for(var key in req.body.proposal) {
//res.send(user.proposal)
//res.send(user)
//res.send(User.username)
user.proposal.insertOne(
{
"uid" : req.body.proposal[key].uid,
"clientEmail" : req.body.proposal[key].clientEmail,
"summary" :req.body.proposal[key].summary,
"terms" :req.body.proposal[key].terms,
"form" :req.body.proposal[key].form
} //update
)
}
user.save()
.then(user => res.json(user))
.catch(err => res.status(400).json('Error: ' + err));
})
.catch(err => res.status(400).json('Error: ' + err));
});
Thank you in advanced!
It should be something like this :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
user.proposal = proposalArr;
user.save().............
You can't use .insertOne on result of database query, it's a function of mongoose model to insert new document to collection but not to insert new fields to objects. You need to do just like adding new fields to json object using .js code, but mongoose will keep track of object's changes & when you use .save() it can update the document in collection with all those changes.
Instead of two DB calls, you can do that in one call, Check : .findByIdAndUpdate() & try below sample code :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
User.findByIdAndUpdate(
req.params.id,
{
proposal: proposalArr
},
{ new: true }
)
.then(user => {
if (!user) res.status(404).send("data is not found");
res.json(user);
})
.catch(err => res.status(400).json("Error: " + err));

Inserting a record from a mongoose model.statics function

I want to create a static function on a mongoose "log" module, which would allow me to write a message as a log entry.
How do I access the model from within the static function? Can I use this.model like below? I don't want to simply use native MongoDB insert command, because I want the model to validate the input, etc.
// ... schema defined above...
var Log = mongoose.model('Log', LogModelSchema)
Log.statics.log = function(message) {
var x = new this.model({message: message})
x.save()
.then(() => { .. do something .. }
.catch((err) => { .. handle err .. }
}
Is this the way it's supposed to be done?
You can make it work like this using this.create:
const mongoose = require("mongoose");
const logSchema = new mongoose.Schema({
message: String
});
logSchema.statics.log = function(message) {
this.create({ message: message })
.then(doc => console.log(doc))
.catch(err => console.log(err));
};
module.exports = mongoose.model("Log", logSchema);
Now you can use this in your routes like this:
Log.log("test");
or just return promise from statics:
logSchema.statics.log = function(message) {
return this.create({ message: message });
};
And use like this:
const Log = require("../models/log");
router.get("/log", (req, res) => {
Log.log("test")
.then(result => {
console.log(result);
res.send("ok");
})
.catch(err => {
console.log(err);
res.status(500).send("not ok");
});
});

Mongoose query - how to create an object for every dataset that is returned

I'm query the database and returning an array of objects, which I then want to create an objet for each set of data based on new object properties as well as push each new object into an array. I believe I'm having problems with the promise not resolved, but can't figure out how to resolve it.
The data from the query returns fine, but its when it enter the for-loop, the object isn't created. It goes into the catch statement.
const express = require('express');
const router = express.Router();
const userTxModel = require('../models/userTx.model');
var RecurringTxObj = (name, user_id, next_amt, next_date, transactions) => {
this.name = name;
this.user_id = user_id;
this.next_amt = next_amt;
this.next_date = next_date;
this.transactions = [];
};
router.get('/getRecurringTx', (req, res) => {
const recurringTxArr = [];
userTxModel
.find({ recurring: true })
.exec()
.then((recurringTxData) => {
for (let data of recurringTxData) {
recurringTxArr.push(
new RecurringTxObj(
data.name,
data.user_id,
data.amount,
data.date,
[]
)
);
}
res.status(200).send(recurringTxArr);
})
.catch((err) => {
console.log('Could not find recurring transactions');
res.status(500).send('Could not find recurring transactions');
});
});
router.get('/error', (req, res) => {
throw new Error('Something went wrong');
});
module.exports = router;

ES6 Promises in express app not properly resolving data

I'm writing an a async function with ES6 promises, that 1) saves the query parameters for a user 2) fetches data from mongodb using mongoose, 3) manipulates the json into a DSL, 4) and queries another db with it.
mongoose": "^4.7.7"
//myController.js
const myQuery = require('../models/myQuery_model');
require('mongoose').Promise = global.Promise
const uuidV4 = require('uuid/v4');
exports.saveNewQuery = function(req, res, next) {
const rawQuery = req.body;
const queryToStore = new myQuery(rawQuery);
const uid = uuidV4();
const queryToStore.uid = uid
queryToStore.save().then(() => {
fetchQueryFromMongo(uid);
}).then((storedQuery) => {
compileQueryToString(storedQuery);
}).then((queryString) => {
fetchResultsFromOtherDb(queryString);
}).then((results) => {
res.json({ results });
}).catch((error) => {
console.log(error)
})
}
Currently I'm not able to resolve the response from mongodb step 2. Still, the controllter goes on to compileQueryToString rather than catch the error from fetchQueryFromMongo
// fetchQueryFromMongo.js
const myQuery = require('../models/myQuery');
require('mongoose').Promise = global.Promise
module.exports = (uid) => {
return new Promise(
(resolve, reject) => {
myQuery.find({ uid }).then((err, res) => {
if (err) {
reject(err);
}
console.log('response success!')
resolve(res);
});
}
);
};
I'm new to promises so any tips / suggestions would be appreciated!
Make sure to return a value from your then handlers. The code below does this by using the concise body form of arrow functions.
queryToStore.save()
.then(() => fetchQueryFromMongo(uid))
.then(storedQuery => compileQueryToString(storedQuery))
.then(queryString => fetchResultsFromOtherDb(queryString))
.then(results => res.json({ results }))
.catch(console.log);

How to save mongoose data after PATCH?

My Feathers.js app has a questionnaire and I'm trying to save the results for each input. Here is my client-side code:
$.ajax({
url: "/answer",
type: "PATCH",
data: newAnswer,
success: function () {
console.log("Answer submitted!");
},
error: function () {
console.log("Error submitting answer.");
}
});
And here is my server-side code:
app.patch("/answer", (req, res) => {
users.patch(user[0]._id, req.body);
});
Currently, only the last input is saved. What am I doing wrong?
EDIT: Here is my schema
answers: {
yourOrganization: {
page1: {
idOfParameterInClient: response
}
}
}
The idOfParameterInClient and the response are dynamic. In page1, there are a number of key/value pairs. How do I keep them?
patch does not do a recursive merge (neither will MongoDB). If that is what you are looking for you will have to do it yourself e.g. using the deepmerge package:
const merge = require('deepmerge');
app.patch("/answer", (req, res) => {
const id = user[0]._id;
users.get(id).then(user => {
const mergedUser = merge(user.toObject(), req.body);
users.patch(id, mergedUser);
});
});
#Daff put me on the right track. In the end, object-patch allowed me to do recursive merges. Here is my code:
const patch = require("object-patch");
app.patch("/answer", (req, res) => {
const id = user[0]._id;
users.get(id).then(user => {
patch(user, req.body);
users.update(user._id, user);
});
});
👍🏾