Inserting a record from a mongoose model.statics function - mongodb

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");
});
});

Related

MongoDB How to define a query for find an object in array, but the array exist of Object references

Basically what I want to do is that I have an ObjectId of a qr. I want to use that ObjectId to find out which qrBlock does it belong. Im leaving my dbmodel here
so you can track easily.
qrRoute.post("/scanQr", (req, res) => {
let { data } = req.body;
var id = mongoose.Types.ObjectId(data);
Qr.findById(id)
.exec()
.then((qrr) => {
QrBlock.find({ qr: { "qr.$": id } }, (qrblck) => {
console.log(qrblck);
});
});
});
I tried this code above it didn't work.
did you try this way
qrRoute.post("/scanQr", (req, res) => {
let { data } = req.body;
var id = mongoose.Types.ObjectId(data);
Qr.findById(id)
.exec()
.then((qrr) => {
QrBlock.find({ qr: id }, (qrblck) => {
console.log(qrblck);
});
});
});
QrBlock.findOne({ qr: { $all: [qrr._id] } })
this worked for me

How to save multiple data on mongoose

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;

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;

Waterline ORM assign the result of find to a variable

I want to combine the results of 2 queries and then return them as one, like this:
test: async (req, res) => {
const valOne = TableOne.find({ id: id })
.exec((err, result) => {
if (err) {
res.serverError(err);
}
return result;
});
const valTwo = TableTwo.find({ id: id })
.exec((err, result) => {
if (err) {
res.serverError(err);
}
return result;
});
const data = {
keyOne: valOne,
keyTwo: valTwo,
};
res.json(data);
}
I understand above code won't return because it's async. How can I achieve this?
There is not much info you supply: node version, sails version, etc.
There are several approaches here:
1. Using promises
2. Using callback chaining
3. Using await/async
If you use sails 1.0 and node >= 8, your best bet is to use await/async, so your code should work like that:
test: async (req, res) => {
let valOne, valTwo;
try {
valOne = await TableOne.find({ id: id });
valTwo = await TableTwo.find({ id: id });
} catch (err) {
return res.serverError(err); //or res.badRequest(err);
}
const data = {
keyOne: valOne,
keyTwo: valTwo,
};
res.json(data);
}

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