I've read the feathersjs documentation, but after doing a find method in a service I realized that if I don't give any query parameters, the service returns all the data, which is something I don't want. How can I define a hook to validate that there are at least one query parameter in order to proceed; otherwise, send back a 403 error (bad request).?
I have doubts in the way to do it I tried this:
app.service('myService')
.before(function(hook) {
if (hook.params.query.name === undefined){
console.log('There is no name, throw an error!');
}
})
.find({
query: {
$sort: {
year: -1
}
}
})
And I tried in hook file on hooks this (that seemed really desperate & | stupid):
function noparams (hook) {
if (hook.params.query.name === undefined){
console.log('There is no name, throw an error!');
}
}
module.exports = {
before: {
find: [ noparams(this) ] ...
}
}
but it does not compile (I don't know what to send as a parameter there), and the examples seemed to be for pre 2.0 version and on top of that the code I found seemed to be in the app.js, but all is differently coded using feathers-cli, so the examples, even in the book, aren't against the scaffolded version, which is confusing because they shows the code in a different file were should be.
Thanks.
I ended using a before hook, so the code used is this:
const errors = require('feathers-errors');
module.exports = function () {
return function (hook) {
if(hook.method === 'find'){
if (hook.params.query.name === undefined || hook.params.query.length == 0){
throw new errors.BadRequest('Invalid Parameters');
}else{
return hook;
}
}
}
};
If have used feathers-cli to generate your application (feathers v2.x) you don't need to do anything else. If is an earlier version you maybe need to add the Express error handler and it is pointed out in the documentation|Errors|REST.
Thanks.
Related
i feel a bit embarrassed, can you please kindly explain parts of the code?
For example, I have no idea, what is this part? where can I read more about it?
function parsePostStory(data) {
return {
name : data.name
}
}
What is req.body? Is it json req body?
Why do we declare empty array and why do we return it? Just for the clarity?
Is Story.create just a mongoose method?
The rest of the code is here:
router.post('/stories', function(req, res) {
var validation = validatePostStory(req.body);
if(validation.length > 0) {
return res.badRequestError(validation);
}
var story = parsePostStory(req.body);
Story.create(story, function(err, story) {
if(err) {
console.log(err.message);
return res.internalServerError();
} res.send(story);
});
});
function validatePostStory(data) {
var array = [];
if (!data.name || typeof data.name !== 'String') {
return array.push('name');
}
return array;
}
function parsePostStory(data) {
return {
name : data.name
}
}
Sorry once more for that kind of a question and thanks a ton.
I'm assuming you know how the request-response cycle works with HTTP requests and the client-server interactions with it. If not, Wikipedia Request-Response and Client-Server (Two link limit, otherwise I would have posted them as links)
A request sends a lot of information to the server. If you console.log the request in NodeJS, you will see that it contains a lot of information that isn't entirely relevant to what you need.
You're using Express as your web framework. In this case, req.body is the information that you are sending to the server from the client. Using req.body will make sure that you're not using the extra information passed in to the server from the client. Req.body is your code that you want. (Note: Req.body isn't natively supported by Express v4, you'll have to use something like body-parser) See Express docs for more details
Now, let's break up this code a bit. You essentially have 3 separate functions. Let's take a look at validatePostStory.
function validatePostStory(data) {
var array = [];
if (!data.name || typeof data.name !== 'String') {
return array.push('name');
}
return array;
}
This function is a validation function. It takes one argument - an object and returns an array. Effectively, what this is doing is checking if the name is a string or not - if not, return an array that has a length of 1. The following conditional checks length and returns a 400 if greater than 0
if(validation.length > 0) {
return res.badRequestError(validation);
}
I'm not entirely sure why this needs to be a separate function. Looks like you can probably just do this instead.
if (!req.body.name || typeof req.body.name !== 'String') {
return res.badRequestError(validation);
}
The following function function essentially converts the data so that mongodb/mongoose can store it in the proper format
function parsePostStory(data) {
return {
name : data.name
}
}
It's the same as saying:
var story = {name: req.body.name}
I would assume Story.create is a custom mongoose method yes.
Followup from this question > Stopping response if document isn't found since it was recommended I use Promise.
So basic premise, I want node to return "Can't find ID" message if we can't find the id in our database.
v1.post("/", function(req, res) {
// If the project_id isn't provided, return with an error.
if ( !("project_id" in req.body) ) {
return res.send("You need to provide Project ID");
}
// Check if the Project ID is in the file.
helper.documentExists( ProjectsData, {project_id: req.body.project_id} )
.then(function(c) {
if ( c == 0 ) {
return res.send("The provided Project Id does not exist in our database.");
} else {
var gameDataObj = req.body;
GameData.addGameId(gameDataObj, function (err, doc) {
if (err) {
if (err.name == "ValidationError") {
return res.send("Please send all the required details.");
}
throw err;
};
res.json(doc);
})
};
});
});
And helper.documentExists
module.exports = {
documentExists: function(collection, query) {
return collection.count( query ).exec();
},
};
But the script continues to run after this and prints the "required data not found".
Output:
required data not found
1
I am using native ES6 Promises.
var mongoose = require("mongoose");
mongoose.Promise = global.Promise;
EDIT: Included the entire get route. (will fix those throw err later)
#######POINT 1#########
ProjectsData.count( {project_id: req.body.project_id} )
.then(function(c) {
#######POINT 3#########
if ( c == 0 ) {
console.log("1");
return res.send("The provided Project Id does not exist in our database.");
console.log("2");
}
});
#######POINT 2#########
//some other logic
console.log("required data not found");
Following async workflow: after POINT 1, the promise is created and your handler is attached. Now POINT 2 will continue, while (at some future clock the promise is resolved and you reach POINT 3.
With my limited understanding of your workflow/purpose I'd say simply put POINT 2 code in the else{} of the if at POINT 3 (as you rightly guessed in the comments).
EDIT: thanks to #jfriend00 for pointing out a serious mistake in the previous version of my answer.
Your code essentially results in this:
ProjectsData.count().then(...);
console.log("required data not found");
So, of course the second console.log() is going to run and print. Nothing that happens in the .then() handler runs until long after the console.log() has already run. And, even then, it can't stop other code from running. Promises don't make the interpreter "wait". They just provide structure for you to coordinate your asynchronous operations.
If you want to branch with promises, then you have to branch inside the .then() handler, not after it.
You don't show enough of the rest of what you're doing to know how to recommend a complete solution. We need to see the rest of your request in order to help you with the proper branching based on asynchronous results.
You probably need something like this:
ProjectsData.count( {project_id: req.body.project_id} ).then(function(c) {
if ( c == 0 ) {
return res.send("The provided Project Id does not exist in our database.");
} else {
// put other logic here
}
}).catch(function(err) {
// handle error here
});
I am trying to load an image using the fromURL. The issue is that I'd like it to be able to load a default icon if it is not able to reach the Image server to download the image. Looking at the docs I did not see an error callback for the fromURL function. How are we supposed to catch that the call was not successful and therefore do the appropriate thing? It does not seem that the callback gets called at all when image load was unsuccessful.
You can use fabric.util.loadImage() method instead of fabric.Image.fromURL().
If you look at the fromURL() method implementation, internally it uses the loadImage().
The following code may help you:
fabric.util.loadImage('https://s3-eu-west-1.amazonaws.com/kienzle.dev.cors/img/image2.png', function(img) {
if(img == null) {
alert("Error!");
}else {
var image = new fabric.Image(img);
canvas.add(image).setActiveObject(image);
canvas.renderAll();
}
}, { crossOrigin: 'anonymous' });
Here is the fiddle: http://jsfiddle.net/k7moorthi/30kmn5kL/
once you have done the function, even if theres a mistake the callback keeps running, then you could check for the element (as other said) in this way:
let fabricBackgroundInstance = new fabric.Image.fromURL(imageToUse, (oImg) => {
if(oImg._element == null){
console.error('oImg', oImg._element);
return;
}
You could use getElement() to check this error.
fabric.Image.fromURL('/foo.jpg', (img) => {
if (img.getElement() === undefined) {
console.log('Failed to load image!');
return;
}
// do something on success
}
You can add the second argument isError to your callback function.
fabric.Image.fromURL("your image URL", (img, isError) => {
if (isError) {
console.log('Something Wrong with loading image');
return;
}
// do something on success
}
Also check fabric.js source code of Image.fromURL http://fabricjs.com/docs/fabric.js.html#line21471
I have a chain of promises that could fail at different points. Depending on where it fails, I might want it to do different things. In some places I might want to render a page, other places redirect. The problem I'm finding is when it runs through all the fail functions and then has errors with http.ServerResponse.end() being called numerous times.
Example:
Parse.Promise.as(1).then(function() {
if (apples) {
return apples.fetch().fail(function() { res.redirect('/somewhere') } );
} else {
return {};
}
}).then(function() {
// doing other stuff
},function() {
res.redirect('/elsewhere');
}).fail(function() {
res.render('error.ejs');
});
Should I be doing this a different way?
( I start with as(1) just to get into the promise chain since there are two different starting cases of apples and !apples that both need to continue to the next part of the chain, but only one of them could start the chain since {} can't. Not sure if that's the best way to do that either. )
Just like exceptions, you can throw different errors and get to different places.
Parse.Promise.as(1).then(function() {
if (apples) {
return apples.fetch();
} else {
throw new Error("No Apples");
}
}).then(function() {
// doing other stuff
}).then(null,function(e) {
if(e.message !== "No Apples"){ // can also subclass Error
res.render("error.ejs");
} else {
res.redirect("/elsewhere");
}
});
Note, like I said in your different question - what you really want is .then(null,function(){ rather than .fail usually. It's a poor name choice for .fail on their side imo.
Because I like them, here is the synchronous analogy:
try {
if(apples){
var a = apples.fetch(); // might throw too
} else{
throw new Error("No Apples");
}
}catch(e){
if(e.message !== "No Apples"){ // can also subclass Error
res.render("error.ejs");
} else {
res.redirect("/elsewhere");
}
}
I am using the following node module for validation: https://github.com/chriso/node-validator
Now, suppose I want to check on an user input like this check('abc').isInt(); I noticed that it basically throws an error!
I am pretty new with node.js but it seems to me that having to use try{}catch(e){} blocks every time I need to check on a user input is a bit on an overkill.
wouldn't it make more sense to have something like
if (check('abc').isInt()) {
// Do things here
next(null, stuff_I_want_to_return)
} else next(error);
instead of
try{
check('abc').isInt()
next(null, stuff_I_want_to_return)
} catch(e) { next(e); }
?? I have no idea, please clarify on what is the best approach to have in this case. Thanks in advance.
Their docs say you can do this
var Validator = require('validator').Validator;
var v = new Validator();
v.error = function(msg) {
console.log('Fail');
}
v.check('abc').isInt(); //'Fail'
That way you won't have to do try catch
Check module core-util-is providing functions introduced in Node v0.12.
In your case, method isNumber would be helpful
It's still fairly common in Node.js for synchronous functions to throw as they don't usually have a callback to pass an error to. But, they still need some way to deliver it to calling code and return error; would generally be an unexpected choice.
Though, the documentation for node-validator does include an example for extending Validators with a getErrors() method under "Error Handling."
Validator.prototype.error = function (msg) {
this._errors.push(msg);
return this;
}
Validator.prototype.getErrors = function () {
return this._errors;
}
Which could be used to report errors without throw:
var validator = new Validator();
if (validator.check('abc').isInt()) {
next(null, ...);
} else {
next(validator.getErrors());
}
Note: The _errors property should already be defined after using .check().