Sails Js - Accessing multiple controller at the same time - node.js

I have a problem with accessing multiple controller at the same time,
example I'm accessing the method "access" while "access" is active, I can't use/access the method "other" or other controllers in the client side,
but when the looping in "access" is done, I can use other methods or controllers, is SailsJs controller Single Threading?
access: function (req, res) {
// Assume that I'll generate 1k data and I dont have problem about that
// my problem is while generating 1k data i cant access my other Controller/Method
// any solution about my problem thanks :)
// NOTE** this is just a example of the flow of my program
// In creating data Im using Async
while(x <= 1000) {
Model.create(etc, function (err, ok) {
if(err) console.log(err)
});
x++;
}
res.view('view/sampleview');
},
other: function (req, res) {
res.view('view/view');
},

All controllers and actions are avaible in sails.contollers variavel Mike sails.controllers.mycontroller.access (req, res);
run in parallel, all at same time:
access: function (req, res) {
var createFunctions = [];
while(x <= 1000) {
createFunctions.push(function(done) {
Model.create(etc).exec(function (err, ok) {
if(err) return done(err); // err
done(); //success
});
})
x++;
}
async.parallel( createFunctions, function afterAll(err) {
sails.controllers.mycontroller.other (req, res);
//res.view('view/sampleview');
});
},
other: function (req, res) {
res.view('view/view');
},
run in series, one by one:
access: function (req, res) {
var createFunctions = [];
while(x <= 1000) {
createFunctions.push(function(done) {
Model.create(etc).exec(function (err, ok) {
if(err) return done(err); // err
done(); //success
});
})
x++;
}
// run in series, one by one
async.series( createFunctions, function afterAll(err) {
sails.controllers.mycontroller.other (req, res);
//res.view('view/sampleview');
});
},
other: function (req, res) {
res.view('view/view');
},

Related

How to define global variable inside callback function for Model.findOne in NodeJS, Express, Mongoose app?

In my POST route, im finding two documents from my database, each one with model.findOne. Then I´m trying to take from that one of it´s key/value pair and save it into a variable.
I´ve tried window.______ method, ive tried global._____, but nothing seems to work. I´ve ignored the "var" keyword, but whatever I do, I cant access these variables anywhere else.
app.post("/match", (req, res, next) => {
Team.findOne({name: req.body.team1}, (err, team) => {
if(err) {
console.log(err);
} else {
let eloOne = team.elo; // <-- here is the problem part
}
});
Team.findOne({name: req.body.team2}, (err, team2) => {
if (err) {
console.log(err)
} else {
let eloTwo = team2.elo; // <-- here is the problem part
}
});
console.log(eloOne) // <-- here i want to use the variables
console.log(eloTwo)
}); // please dont kill me for this code, I've started programing recently
Here is the code.
app.post("/match", (req, res, next) => {
Team.findOne({name: req.body.team1}, (err, team) => {
if(err) {
console.log(err);
} else {
let eloOne = team.elo; // <-- here is the problem part
Team.findOne({name: req.body.team2}, (err, team2) => {
if (err) {
console.log(err)
} else {
let eloTwo = team2.elo; // <-- here is the problem part
console.log(eloOne) // <-- here i want to use the variables
console.log(eloTwo)
res.send(' request complete')
}
});
}
});
});
I suggest to use 'async await' or promise atleast.
Use promise.all as it will be doing both the network calls in parallel, and hence increase the performance.
app.post("/match", async (req, res, next) => {
try {
const [team, team2 ] = await Promise.all([Team.findOne({name: req.body.team1}).exec(), Team.findOne({name: req.body.team2}).exec()]),
eloOne = team.elo,
eloTwo = team2.elo;
console.log(eloOne)
console.log(eloTwo)
} catch(error) {
console.log(error);
}
});

How to multiple fetch data expressJS

I want to display chatbot and facebook data at the same time. how to display it? because when I try to run in the browser but it does not appear anything. I've tried to look it up on stackoverflow but did not get the right reference
route.js
app.get('/cpanel/facebook', function(req, res) {
if (req.session.user == null) {
res.redirect('/cpanel/login');
} else {
CB.getAllRecords( function(e, chatbot) {
res.render('cpanel/facebook', { udata : req.session.user, chatbot : chatbot });
});
FBM.getAllRecords( function(e, facebook) {
res.render('cpanel/facebook', { udata : req.session.user, facebook : facebook });
});
}
});
facebook.js
var facebook = db.collection('facebook');
exports.addNewFacebook = function(newData, callback) {
facebook.findOne({accesstoken:newData.accesstoken}, function(e, o) {
if (o) {
callback('accesstoken-taken');
} else {
facebook.insert(newData, {safe: true}, callback);
}
});
}
exports.getAllRecords = function(callback) {
facebook.find().toArray(
function(e, res) {
if (e) callback(e)
else callback(null, res)
}
);
}
chatbot.js
var chatbot = db.collection('chatbot');
exports.addNewChatBot = function(newData, callback) {
chatbot.insert(newData, {safe: true}, callback);
}
exports.getAllRecords = function(callback) {
chatbot.find().toArray(
function(e, res) {
if (e) callback(e)
else callback(null, res)
}
);
}
The easier way to manage asynchronous operations in node.js, especially when you have more than one operation that you want to coordinate is to use Promises instead of plain callbacks. And, fortunately, mongodb supports a promise-based interface for all its asynchronous operations now.
So, first change your methods to return a promise instead of taking a callback:
var chatbot = db.collection('chatbot');
exports.getAllRecords = function() {
return chatbot.find().toArray();
}
var facebook = db.collection('facebook');
exports.getAllRecords = function() {
return facebook.find().toArray();
}
Then, you can use those promises with Promise.all() to coordinate:
app.get('/cpanel/facebook', function(req, res) {
if (req.session.user == null) {
res.redirect('/cpanel/login');
} else {
Promise.all([CB.getAllRecords(), FBM.getAllRecords()]).then(results => {
res.render('cpanel/facebook', { udata : req.session.user, chatbot : results[0], facebook: results[1]});
}).catch(err => {
// render some error page here
res.sendStatus(500);
});
}
});
For a call to just a single function that returns a promise, you can use .then():
app.get('/cpanel/facebook', function(req, res) {
if (req.session.user == null) {
res.redirect('/cpanel/login');
} else {
FBM.getAllRecords().then(results => {
res.render('cpanel/facebook', { udata : req.session.user, facebook: results});
}).catch(err => {
// render some error page here
res.sendStatus(500);
});
}
});

res is not defined in Node.js (Mongoose)

How can I put res in a normal function i.e not an exported one which is not part of routes?
function createNewStudent(v,callBackOne){
if (callBackOne) {
studentInfo.callBackOneStudent = callBackOne;
}
// common filter json
var filterjson = common.defaultFilterJson();
filterjson['active'] = true;
filterjson['email'] = v.email;
// student initialization
var student = new Student(v);
async.waterfall([
function (done) {
student.save(function (err) {
if (!err) {
studentInfo.callBackOneStudent();
Employee.update({_id: student.created_by},{"$push": { "students": student._id } }).exec(function (err, employee) { });
done();
}
});
}
}
});
},
function (done) {
var url = config.mailer.studentActivateUrl + student._id;
---error is here-----
res.render('modules/users/server/templates/student-confirmation-email', {
name: student.first_name + ' ' + student.last_name,
appName: 'GAIPP',
url: url
}, function (err, emailHTML) {
done(err, emailHTML, student);
});
}
});
My error is 'res' is not defined. Can anyone please help me to solve this error?
The only way that you can put res in a function is if you somehow supply it to that function at runtime. Remember that res is meaningful only in request handling. Outside of the request handler your function couldn't even know which request to respond to because there might be several requests served at the same time.
If you want to have a function that has access to res then you have those options:
Use a nested function in your request handler, e.g.
app.get('/foo', function (req, res) {
function x() {
// you can use res here
}
x();
});
Add res as an argument:
function x(res) {
// you can use res here
}
app.get('/foo', function (req, res) {
x(res);
});
Another option would be to add a callback to your function that would be passed by the handler:
function x(args, cb) {
// you cannot use res here
// but you can call the callback:
cb(null, 'something');
}
app.get('/foo', function (req, res) {
x(function (err, data) {
if (err) {
// handle error
}
// use res here with data supplied by x()
res(data);
});
});
Instead of using callback your x() function could also return a promise.

Bookshelf.js limit query

Solved. See below for the answer.
I'm trying to get only a limited amount of results.
While the second one works, the first one doesn't. What's missing here?
First query
app.get('/ind', function (req, res) {
youtube.where('status', 0).fetch(function (qb) {
qb.limit(10);
}).then(function (data) {
data = data.toJSON();
});
});
Second query
app.get('/photos', function (req, res) {
user.where('id', 1).fetch({
withRelated: [{
'photos': function (qb) {
qb.limit(2);
}
}]
}).then(function (data) {
data = data.toJSON();
res.send(data);
});
});
Solved.
All you need is to add a query() before fetchAll() and define your limit inside this query().
app.get('/ind', function (req, res) {
youtube.where('status', 0).query(function (qb) {
qb.limit(10);
}).fetchAll().then(function (data) {
data = data.toJSON();
res.render('youtube', {
mi: data
});
});
});

console.log a GET request with Node.js

I'm using the Express framework for my node application. I'm quite new to it so I thought I'd create a defacto "To-Do" application to learn about it. What I'm trying to do it log a request made for debugging purposes. So when I go to:
app.get('/todos/:id', function (req, res) {
var result = db.load(req.params.id);
result ? res.send(result) : res.send(404);
});
I want to a) see what result equals and b) log what happens in my db.load method:
exports.load = function (id) {
todos.findOne({ id: id }, function (err, todo) {
if (!err) {
return todo;
}
});
}
I'm using the mongolian library to access my MongoDB data. I've followed an example by Steve Sanderson: https://github.com/SteveSanderson/nodejs-webmatrix-video-tutorials
app.get('/todos/:id', function (req, res) {
db.load(req.params.id, function(err, result) {
// also handle err
result ? res.send(result) : res.send(404);
});
});
exports.load = function (id, callback) {
todos.findOne({ id: id }, callback);
}

Resources