Is it possible to inherit blueprint function in sails - node.js

Is it possible to reuse / call the blueprint function (find/create/update/destory) and just add some items needed for the controllers. I'm sorry if I'm having hard time expressing my question but hopefully my example will help.
Example:
modue.exports = function(){
index: ....,
create: function(req, res){
try{
// i want to call the blueprint here to save some things
create(req, res);
// then do more after creating the record
....
}catch(err){
// want to catch some error here like validation err
// instead of sending it to res.serverErr();
}
}
....
}

//File api/controller/UserController.js
// suppose the model is User under api/models
modue.exports = {
create: function(req,res){
// pass req.query to User Model's Create function, so you dont need to rewrite all
//optional paramters for this overwrite version
User.create(req.query).exec(function(e, r){
if(e){
// !!!try to create in a different way!
}
})
}
}

You need to first copy blueprint folder from sails which is present in node_modules folder
Paste the blueprint folder in you api folder
Then in your controller for e.g UserController include actionUtil for e.g
var actionUtil = require('sails/lib/hooks/blueprints/actionUtil');
module.exports = {
create: function (req, res) {
// paste code from blueprint create.js file
var Model = actionUtil.parseModel(req);
// Create data object (monolithic combination of all parameters)
// Omit the blacklisted params (like JSONP callback param, etc.)
var data = actionUtil.parseValues(req);
// Create new instance of model using data from params
Model.create(data).exec(function created(err, newInstance) {
// Differentiate between waterline-originated validation errors
// and serious underlying issues. Respond with badRequest if a
// validation error is encountered, w/ validation info.
if (err)
return res.serverError({status:500, message:'error', err: err});
// If we have the pubsub hook, use the model class's publish method
// to notify all subscribers about the created item
if (req._sails.hooks.pubsub) {
if (req.isSocket) {
Model.subscribe(req, newInstance);
Model.introduce(newInstance);
}
// Make sure data is JSON-serializable before publishing
var publishData = _.isArray(newInstance) ?
_.map(newInstance, function (instance) {
return instance.toJSON();
}) :
newInstance.toJSON();
Model.publishCreate(publishData, !req.options.mirror && req);
}
// do your after create stuff here
// Send JSONP-friendly response if it's supported
res.ok({status: 200, message: 'ok', results: newInstance});
});
}
}

Related

"Dynamic route" with expressjs

I want to create a route which can change while the program is running.
Example : app.get('/',function(req,res){/*Something here*/}; This is a normal route.
I want to replace the '/' with a variable which can be replaced with a random number. After that I'll create a qrcode with a nodejs module and the user who scans this qrcode will confirm a kind of transaction.
If you understand my idea and you have a solution, I'll take it.
As #Louy said, use parameters:
var getQRCode = require('./yourQRCodeModule');
app.param('qrcode', function(req, res, next, qrcode) {
// qrcode will be "1234" if your request path was "/1234"
console.log('checking qrcode: %s', qrcode);
// get the qrcode from some asynchronous function
getQRCode(qrcode, function callback(err, qrcode) {
// if this number was not a valid dynamic path, return an error from your module
console.log('qrcode was %s', (!err && qrcode) ? 'valid' : 'invalid');
if (err) {
next(err);
} else if (qrcode) {
req.qrcode = qrcode; // object from your module
next();
} else {
next(new Error('failed to load QR code'));
}
});
});
app.get('/:qrcode', function (req, res) {
// req.qrcode will be the object from your module
// if the number was invalid, this will never be called
});
What I'm trying to point out is that you're thinking of this scenario differently than how express approaches the problem. You want a one-time route with a specific qrcode, but these kind of routes don't exist in express. So here's what I understand your ideal solution to look like:
server creates "azjzso1291084JKioaio1" for a qrcode
you register something like app.getOnce("azjzso1291084JKioaio1", function(req, res){...})
first time the request gets called, it's removed from your express router
Here's what I'm suggesting:
server creates "azjzso1291084JKioaio1" for a qrcode
your module stores this qrcode either in a database or in memory, within your module, e.g. var qrcodes = {}; qrcodes["azjzso1291084JKioaio1"] = {some: 'object'};
your app.param asynchronous function based on the example given in step 2 could look like this:
// yourQRCodeModule.js
var qrcodes = {};
qrcodes["azjzso1291084JKioaio1"] = {some: 'object'};
module.exports = function getQRCode(qrcode, callback) {
if (qrcodes[qrcode]) {
var obj = qrcodes[qrcode]; // copy object
delete qrcodes[qrcode]; // remove from memory here
callback(null, obj);
} else {
// invalid path
callback(new Error('invalid QR code'), null);
}
};
Now notice if you request /azjzso1291084JKioaio1 twice, the second time fails. This is how you intend it to work, if I am not mistaken.

How to control a PUT request with NodeJS Express

I need to set a ReST API with my NodeJS Express 4 Application.
Currently, this is my API.
I have a families resource which exposes several HTTP verb.
GET to perform a read in my MongoDB database.
GET with familyID to get the family with the id familyID
POST to create a new family in the database.
PUT to update a family.
I want to follow the ReSTful theory so I'd like to control when a PUT is done that all the resource is modified and not a part of it (which is a PATCH verb).
This my nodejs route controller code :
// Main Function
router.param('famillyId', function(req, res, next, famillyId) {
// typically we might sanity check that famillyId is of the right format
Familly.findById(famillyId, function(err, familly) {
if (err) return next(err);
if (!familly) {
errMessage = 'familly with id ' + famillyId + ' is not found.';
console.log(errMessage);
return next(res.status(404).json({
message: errMessage
}));
}
req.familly = familly;
next();
});
});
/PUT
router.put('/:famillyId', function(req, res, next) {
console.log('Update a familly %s (PUT with /:famillyId).', req.params.famillyId);
req.familly.surname = req.body.surname;
req.familly.firstname = req.body.firstname;
req.familly.email = req.body.email;
req.familly.children = req.body.children;
req.familly.save(function(err, familly) {
if (err) {
return next(err);
}
res.status(200).json(familly);
});
});
I'd like to know what is the best way to do this control. I don't want to use a series of 'if' for each record of my JSON object. Is there an automatic way of doing it ?
Just to avoid this kind of code :
if (req.familly.surname)
if (! req.body.surname)
return next(res.status(200).json('{"message":"surname is mandatory"}‘)));
Doing this kind of things for each property in my JSON Object is very boring, lots of code to type for nothing.
I looking forward a clean code to do it.
Thanks.
Hervé
var control = ['surname', 'firstname', 'email', 'children'];
control.forEach(function(arg){
if(!req.body[arg]){
return next(res.status(200).json({"message": arg + " is mandatory"}));
}
});

Mock function return in node.js test

I'm new to testing in node.js and I would like to mock the return of a specific function call in a process that looks like the following.
doSomething(function(err, res){
callAnotherOne(res, function(err, result){
getDataFromDB(result, function(err, docs){
//some logic over the docs here
})
})
})
The function that I want to mock is the getDataFromDB() and specifically the documents (using MongoDB) that it returns.
How could I do something like this with mocha?
Part of the code, strip from the logic in between, is the following:
filterTweets(item, input, function(err, item) {
//Some filtering and logging here
db.getTwitterReplies(item, function(err, result) {
if(err) {
return callback('Failed to retrieve tweet replies');
}
//Do some work here on the item using the result (tweet replies)
/***** Here I want to test that the result is the expected ****/
db.storeTweets(item function (err, result){
//error checks, logging
callback();
});
});
});
Based on the amount of twitter replies (function call "getTwitterReplies"), I will modify my object accordingly (didn't include that code). I want to see if based on different replies result, my object is constructed as expected.
p.s. I also checked into sinon.js after some searching and I managed to mock the return of a callback (by writing some testing code outside my project) but not the return of a callback of a nested function call.
Here's how I would approach this category of problem:
First create a "config.js" that wraps the dependencies that you'd like to inject. This will become your container.
var db = {
doSomeDbWork : function(callback){
callback("db data");
}
};
module.exports = {
db: db
};
From there, you can call config dependencies like so:
var config = require('./index/config');
config.db.doSomeDbWork(function(data){
res.render('index', { title: 'Express' , data:data});
});
And in your tests, inject a mock/spy easily:
var config = require('../routes/index/config');
config.db = {
doSomeDbWork : function(callback){
callback("fake db data");
}
};
var indexRouter = require('../routes/index');
indexRouter.get('/');
Because the require call refers to the same config module exports, the changes made to the config in the spec will be reflected where ever they are imported via require()

Angularjs passing variables from controller to dao service

I am trying to pass a variable from the controller to my DAO service in an Angularjs application (frontend) and nodejs backend.
here is my controller :
$scope.afficherProfils = function() {
$http.get(configuration.URL_REQUEST + '/profile')
.success(function(data) {
$scope.owner = data._id;
console.log('$scope.owner =========>');
console.log($scope.owner);
$http.get(configuration.URL_REQUEST + '/listerProfil', {
owner: $scope.owner
})
.success(function(data) {
console.log('$scope.listeProfils =========>');
console.log(data);
$scope.listeProfils = data;
});
});
};
i am calling /profile to get the _id of the account that has added the profile, after that i call /listerProfil inside success and pass the owner parameter.
and in my DAO service the code is the following :
exports.all = function(req, res) {
console.log('req.body ================================>');
console.log(req.body);
Profil.find({
owner: req.body.owner
}, function(err, profils) {
if (err) {
res.send({
'result': 'error'
});
} else {
res.send(profils);
}
});
};
and i don't know why my req.body is empty when i do a console.log
any ideas ?
HTTP-CRUD(Create-$http.post,Read-$http.get,Update-$http.put,Dlete-$http.delet)
$http.get-It used to get the value means this body contain empty value
$http.post-It used to create value means this body contain data (your are post some data to server)
$http.update-It used to update exit value this body also contain data
$http.delete-It used to delete exit value this body contain empty(send through param(?id=1111))
so change your code http.get to http.post

Can Express alter incoming requests and redirect to a different method after alteration?

I have an Express (v3) app where (in an ideal scenario) a user types a string into an input field, waits for an autocomplete function to return a list matching the string, and chooses from that list, thereby adding an 'id' value to a hidden field. When they click 'Go', their request is routed to this endpoint with their query:
app.get('/predict', function(req, res) {
// req.query should be something like
// { name: "wat", id: 123 }
res.render('predictions');
}
I want to change this functionality slightly, so that if the req.query.id is empty (i.e. the user didn't wait for the autocomplete), I don't have to redirect them back saying "Please wait for the autocomplete".
In my mind, I want to extend the above endpoint to do something like
app.get('/predict', function(req, res) {
// req.query is { name: 'wat', id: '' }
if(req.query.id=='') {
// then the user didn't wait for the autocomplete, so
// guess the id ourselves
} else {
// ... some code
res.render('predictions');
}
}
In guessing the ID for myself, I'm using the same external API as I use for my autocomplete function, which returns an array of results with confidence values based on a query parameter, i.e. how likely it thinks the result is what I want.
Now we get to the question. Can I do something like this?
app.get('/predict', function(req, res) {
// req.query is { name: 'wat', id: '' }
if (req.query.id=='') {
makeRequestToAPIWithQuery(req.query.name, function(err, suggestions) {
// suggestions[0] should contain my 'best match'
var bestMatchName = suggestions[0].name;
var bestMatchId = suggestions[0].id;
// I want to redirect back to *this* endpoint, but with different query parameters
res.redirect('/predict?name='+bestMatchName+'&id='+bestMatchId);
}
} else {
// some code
res.render('predictions');
}
}
I want the server to make a different request to itself if req.query.id is empty. So after the redirect, req.query.id shouldn't be empty and res will render my 'predictions' view as required.
Is this possible/wise/safe? Am I missing something?
Big thanks in advance.
express routers accept several handlers as middleware.
You could test for the presence of the id in the first handler and populate your request object accordingly and then do as nothing happened in the original handler.
function validatePredictForm(req, res, next) {
if(!req.query.id) {
req.query.id = 'there goes what your want the default value to be';
return next();
}
else {
// everything looks good
return next();
}
}
app.get('/predict', validatePredictForm, function(req, res) {
// req.query should be something like
// { name: "wat", id: 123 }
res.render('predictions');
});

Resources