how to execute MongoDB statements in strongloop's remote method - javascript

Hi My task is to create an remote method using strongloop & execute an mongoDB function for the rest API. my mongoDB is like
"db.users.count({user_email_id :"bhargavb#ideaentity.com",user_password:"5f4dcc3b5aa765d61d8327deb882cf99",isdeleted:1,user_status:1});
if (count=1) then"
to execute this in strongloop I'm trying something like
module.exports = function(GetUserFind) {
var server = require('../../server/server');
var db = server.dataSources.MongoTours;
db.connect(function(err, db) {
if (err) return console.log('error opening db, err = ', err);
console.log("db opened!");
GetUserFind.login = function(par,par2,par3,par4,cb){
console.log(par,par2,par3,par4);
db.collection('users', function(err, collection) {
console.log("the collection is"+ collection);
if (err) return console.log('error opening users collection, err = ', err);
collection.count ({user_email:par}, function(err, result) {
if(err) {
console.error(err);
return;
}
cb(null,result);
});
cb(null,par,par2,par3,par4);
});
}
});
GetUserFind.remoteMethod(
'login',
{
accepts: [{arg: 'user_email_id', type: 'string'},
{arg: 'user_password', type: 'string'},
{arg: 'isdeleted', type: 'number'},
{arg: 'user_status', type: 'number'}],
returns: {arg: 'result', type: 'object'},
http: {path:'/Loogin', verb: 'get'}
}
);
// db.close();
}
but I'm not able to do the same, can anyone tell me how can i execute mongoDB statements in strongloop remote methods
thanks in advance

I tried it the following way,
module.exports = function(GetUserFind) {
var response = 'User does not exists';
var server = require('../../server/server');
var sha256 = require('js-sha256');
// getUser function login declaration
GetUserFind.login = function(par, par2, cb) {
console.log(par, par2);
// calling users collection method
var MongoClient = require('mongodb').MongoClient;
var self = this;
this.callback = cb;
// to connect to mongoDB datasource
MongoClient.connect('mongodb://192.168.0.78:27017/tours', function(err,
db) {
console.log(sha256(par2));
if (err) {
// try{
console.log(err);
}
db.collection('users').find({
user_email_id : par,
user_password : sha256(par2)
},{user_password:0}).toArray(function(err, result) {
//https://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/
if (err) {
throw err;
}
if (result.length > 0) {
self.callback(null, result);
// db.disconnect();
} else {
self.callback(null, response);
// db.disconnect();
}
});
});
}
GetUserFind.remoteMethod('login', {
// passing input parameters
accepts : [ {
arg : 'user_email_id',
type : 'string'
}, {
arg : 'user_password',
type : 'string'
} ],
// getting output parameters
// returns: {arg: 'user_email_id', type: 'string'},
returns : [ {
arg : 'result',
type : 'object'
} ],
http : {
path : '/Loogin',
verb : 'get'
}
});
// db.close();
};
This may help other.
If any one knows better & easy way, Please post or update the answer

Related

nodejs mongoDB findOneAndUpdate(); returns true even after database is updated

i am working on an Ionic-1 + nodejs + angular application. My mongoDb findOneAndUpdate() function returns true on each call even the first call updates database.
nodejs:
app.post('/booking', function (req, res) {
var collection = req.db.get('restaurant');
var id = req.body.id;
var status = req.body.status;
collection.findOneAndUpdate({status: status, id: id},{$set:{status:"booked"}}, function (e, doc) {
console.log(id, status);
if (e) {
console.log(e);
}
else if(!doc) {
res.send(false);
}
else {
res.send(true);
}
});
});
controller.js
$scope.bookMe = function(id){
var Obj = {status: "yes", id: id};
myService.booking(Obj).success(function(res){
console.log(Obj, "Checking status")
console.log(res);
if (res == true) {
var alertPopup = $ionicPopup.alert({
title: 'Booking Confirm',
template: 'Thanks For Booking'
});
}
else{
var alertPopup = $ionicPopup.alert({
title: 'Error',
template: ' Not available'
});
}
})
};
where i am doing wrong. my DB gets updated but it returns true always on next call.
The documentation about findOneAndUpdate says :
Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. The query executes immediately if callback is passed.
So it's regular behavior you got a doc.
Note:
Since you are checking availability status="yes", Better hard code, instead of getting it from request query/data.
Change the response according to your requirement res.send(true)/ res.send(false).
Following code will work
app.post('/booking', function (req, res) {
var collection = req.db.get('restaurant');
collection.findOneAndUpdate({
status: "yes",
_id: req.body.id
}, {
$set: {
status: "booked"
}
}, function (err, result) {
//Error handling
if (err) {
return res.status(500).send('Something broke!');
}
//Send response based on the required
if (result.hasOwnProperty("value") &&
result.value !== null) {
res.send(true);
} else {
res.send(false);
}
});
});

Mongo Returns full data while Mongoose does not return relative data

When I use mongo Command Prompt to get data, it works fine:
But when I do it using mongoose in node.js, I don't get referenced data.
Here is my code:
In Model:
module.exports.getOrderBysalesOrderId = function(salesOrderId, callback){
Order.find({salesOrderId: salesOrderId}).exec(function(err, order){
if(err) return callback(err, null);
callback(null, order);
});
};
In Route:
router.get('/:salesOrderId', function(req, res, next){
var salesOrderId = req.param('salesOrderId');
console.log('order with 1 param is called.');
Order.getOrderBysalesOrderId(salesOrderId, function(err, order) {
if (err) {
return console.error(err);
} else {
//respond to both HTML and JSON. JSON responses require 'Accept: application/json;' in the Request Header
res.format({
//response in dust or jade files
html: function(){
res.render('Order', {
title: 'Order',
"order" : order
});
},
//JSON response will show all orders in JSON format
json: function(){
res.json(order);
}
});
}
});
});
Then using Ajax, I try to get the data and print it to console:
$.ajax(
{
type: "GET",
url: "/Order/" + orderNo,
dataType:"json",
async: false,
beforeSend: function(jqXHR, settings)
{
console.log(settings.url);
},
success: function(order)
{
console.log(order);
templateData = order;
},
error: function(xhr, textStatus, errorThrown)
{
alert('ajax loading error... ... '+ url + query);
}
});
Output in Console:
Update:
Here is the structure of my model:
var mongoose = require('mongoose');
var orderSchema = new mongoose.Schema({
salesOrderId: String,
orderDate: Date,
party: {type: mongoose.Schema.Types.ObjectId, ref:'Party'},
items:[{type: mongoose.Schema.Types.ObjectId, ref:'Item'}, {quantity: Number}, {rate: Number}],
dispatches:{
invoiceId: Number,
dispatchDate: Date,
items: [{type: mongoose.Schema.Types.ObjectId, ref:'Item'}, {quantity: Number}, {rate: Number}]
}
});
Update2:
When I try to get data using populate(), here is my query:
module.exports.getOrderBysalesOrderId = function(salesOrderId, callback){
Order.find({salesOrderId: salesOrderId}).populate("items").exec(function(err, order){
console.log(order);
if(err) return callback(err, null);
callback(null, order);
});
};
Here I get error:
Update3:
Now I tried the below mentioned code in model:
module.exports.getOrderBysalesOrderId = function(salesOrderId, callback){
salesOrderId = mongoose.Types.ObjectId(salesOrderId);
Order.find({salesOrderId: salesOrderId}).populate("party").exec(function(err, order){
console.log(order);
if(err) return callback(err, null);
callback(null, order);
});
};
Here is my db.js file:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/RateDifferenceDB')
Now, I get another error:
I also get a url error in console of browser:
I should use lean function to get results :
module.exports.getOrderBysalesOrderId = function(salesOrderId, callback){
Order.find({salesOrderId: salesOrderId}).lean().exec(function(err, order){
if(err) return callback(err, null);
callback(null, order);
});
};

What's the proper use of Bluebird or Q Promises in this situation?

I'm using a node machines package (machinepack-wepay) to communicate with Wepay and I'd like to be able to chain it properly.
Take the following example where we will be registering a user, creating an account and sending the email confirm. Along the way we will be storing some of the result info in mongo.
var WePay = require('machinepack-wepay');
// ... extraneous code removed for brevity
var member = req.session.member;
if( !_.has( member, 'wepay' ) ) {
WePay.userRegister({
clientId: config.wepay_client_id,
clientSecret: config.wepay_client_secret,
email: member.email,
scope: 'manage_accounts,collect_payments,view_user,send_money',
firstName: member.firstName,
lastName: member.lastName,
originalIp: req.headers['x-forwarded-for'],
originalDevice: req.headers['user-agent'],
tosAcceptanceTime: Math.floor(new Date() / 1000),
callbackUri: config.site_url + '/wepay/user?member=' + member.id,
useProduction: isProd
}).exec({
error: function (err) {
yourErrorHandler(err);
},
success: function (result) {
Member.update({id: member.id}, {wepay: result}, function (err, updated) {
if (err) {
yourErrorHandler(err);
}
else {
member = updated[0];
WePay.accountCreate({
accessToken: member.wepay.access_token,
name: 'Account Name',
description: 'My new account'
}).exec({
error: function (err) {
yourErrorHandler(err);
},
success: function (result) {
Member.update({id: member.id}, {wepay_account: result}, function (err, updated) {
if (err) {
sails.log.error("error updating page:", err);
}
req.session.member = updated[0];
// PATTERN CONTINUES HERE
});
}
});
}
});
}
});
}
else{
WePay.userDetails({
accessToken: member.wepay.access_token,
useProduction: false,
}).exec({
error: function (err){
yourErrorHandler(err);
},
success: function (result){
_.extend( member.wepay, result );
Member.update({id: req.session.current_page.id}, member, function (err, updated) {
if (err) {
sails.log.error("error updating page:", err);
}
req.session.member = updated[0];
// PATTERN CONTINUES HERE
});
},
});
}

node express with orm2 & separated model files

I am using node & express (framework for node).
I wan't to use the node-orm2 framework for node for communicating with my MySQL database. To keep a nice structure I want to split up my models in separated files. I've been using the documentation on github but somehow I can't make it work.
app.js:
app.use(orm.express("mysql://********:********#localhost/*********",
{
define: function(db, models){
db.load('./models', function(err){
models.movie = db.models.Movie;
});
}
}));
models.js:
module.exports = function (db, fn) {
db.load("movie", function (err) {
if (err) {
return fn(err);
}
});
//etc
return fn();
};
movie.js:
module.exports = function (db, fn) {
db.define('movie', {
id : { type: "number" },
title : { type: "text" },
year : { type: "number" },
rating : { type: "number" },
description : { type: "text" }
}, {
methods : {
}
});
return fn();
};
Copied help from github issue tracker (from lastmove):
I am using the built in express middleware.
It works fine for me.
I have a folder Model.
With one file par model.
Example the user model:
user.js
module.exports = function(db, cb)
{
var User = db.define('user', {
userName : String,
password : String,
mail : String,
mark : Number,
lastAlertSent : Date,
subscriptionDate : Date,
lastAction : Date,
specialUser : Boolean,
uuid : String
},
{
validations:
{
userName : [orm.enforce.required(error.errorStr(error.missingRequiredField, "userName missing")), orm.enforce.unique({ ignoreCase: true }, error.errorStr(error.usernameAlreadyUsed, "userName already used")), orm.enforce.ranges.length(3, undefined, error.errorStr(error.usernameTooShort, "userName too shoty"))],
...
And in the Models folder i have an index.js
In this file i define the relations betweens my models, and I load my models.
File:
models/index.js
checkError = function(cb, err)
{
if (err)
return cb(err);
return cb();
}
module.exports = function(db, cb)
{
db.load("./user.js", function (err) {checkError(cb, err)});
db.load("./alert.js", function (err) {checkError(cb, err)});
db.load("./comment.js", function (err) {checkError(cb, err)});
db.load("./metropole.js", function (err) {checkError(cb, err)});
db.load("./period.js", function (err) {checkError(cb, err)});
db.load("./stop.js", function (err) {checkError(cb, err)});
db.load("./line.js", function (err) {checkError(cb, err)});
db.load("./types.js", function (err) {checkError(cb, err)});
db.load("./historique.js", function(err) {checkError(cb, err)});
var User = db.models.user;
var Alert = db.models.alert;
var Comment = db.models.comment;
var Metropole = db.models.metropole;
var Stop = db.models.stop;
var Line = db.models.line;
var Period = db.models.period;
var Types = db.models.types;
var Hist = db.models.historique;
Alert.hasOne("stop", Stop, {reverse : "alerts"});
Alert.hasOne("line", Line, {reverse : "alerts"});
and after all in my Express initialization i add this:
app.use(orm.express(opts, {
define: function (db, models, next) {
db.load("./models/models", function (err2)
{
if (err2)
throw err2;
db.sync();
})
next();
}

node.js - How to return an ObjectId by name in Mongoose

I have this code for setting an ObjectID to brand property of an productSchema:
productSchema.path('brand').set(function (namebrand) {
var brandID;
Brand.findOne({ 'name': namebrand }, 'id name', function (err, result){
if (err) console.log(err);
if (result){
// console.log("Result: "+result);
brandID = result.id;
} else {
var newBrand = new Brand({name:namebrand});
newBrand.save(function (err, newBrandID){
console.log("newBrandID : "+newBrandID)
brandID = newBrandID.id;
});
}
});
return mongoose.Types.ObjectId(brandID);
});
My problem is when the Brand ObjectID setter executes, I got differents ObjectId's
for example:
return mongoose.Types.ObjectId(brandID); // 52ffaa218050b7c4652502de
console.log("newBrandID : "+newBrandID) // newBrandID : { __v: 0, name: 'new Brand name', _id: 52ffaa218050b7c4652502df }
So what is the correct way to do what I want? I'm a newbie on this :/
P.S.: Thanks in advance, and sorry for my English.
You can't use a return value here. A mongoose set needs to be synchronous and you are making a DB query which is asynchronous. Look up the brand in the DB first, then set it on the product.
var productModel; // you must already have loaded this
var namebrand = "somebrand";
Brand.findOne({ 'name': namebrand }, 'id name', function (err, result){
if (error) {
console.error(error);
return;
}
if (result){
productModel.brand = result._id;
} else {
var newBrand = new Brand({name:namebrand});
productModel.brand = newBrand._id
newBrand.save(function (err, newBrandID){
console.log("newBrandID : "+newBrandID)
brandID = newBrandID.id;
});
}
productModel.save();
});

Categories

Resources