JS, correct syntax from arrow to normal - javascript

Im learning and trying to understand javascript, and in a video im following, the dude used this code
app.post('/content/uploads', (req,res) => {
upload(req, res, (err) => {
console.log(req.file);
res.send('testing');
})
});
now im trying to convert it to normal, i understand that app.post('/content/uploads', (req,res) => {
translates to app.post('/content/uploads', function(req, res){
but when i try to do upload(req, res, (err) => {, i cant.
What i tried is
upload(function(req, res, (err)){
but i get an error in
upload(function(req, res, (err)){
^
SyntaxError: Unexpected token '('
what is the correct way to translate it?
My full failed translation looks like this
app.post('/content/uploads', function(req, res){
upload(function(req, res, (err)){
if(err){
res.render('index', {
msg: err
});
} else {
console.log(req.file);
res.send('test');
}
});
});
Thanks

I suggest you spend some time getting comfortable with the arrow syntax, it's not "abnormal".
In any case, you may find this tool useful: https://babeljs.io/en/repl
You can paste code and select only ES2015 on the left (uncheck the others) and see how it translates the code.
For example, it will output:
app.post('/content/uploads', function (req, res) {
upload(req, res, function (err) {
console.log(req.file);
res.send('testing');
});
});

app.post('/content/uploads', function (req,res) {
upload(req, res, function (err) {
console.log(req.file);
res.send('testing');
})
});

upload(req, res, (err)=>{
//TODO
});
The above code is equivalent to:
var someFunc = (err)=>{
//TODO
};
upload(req, res, someFunc);
So, you can write it with function keyword like this:
upload(req, res, function (err) {
//TODO
});

Related

Handle multer.single('file') error when upload multiple files

I followed the Multer code:
app.post('/profile', upload.single('avatar'), function (req, res, next) {
})
One single file should be uploaded. But if one tries to upload multiple files, how to catch the error MulterError: Unexpected field?
I have tried below to no success:
app.post('/profile', upload.single('avatar'), function (req, res, next) {
try {
} catch (error) {
// Why cannot catch any error?
}
})
when upload.single executes next() then only it comes here,
app.post('/profile', upload.single('avatar'), function (req, res, next) {
try {
} catch (error) {
// It catches only errors from above `try block`
}
});
If upload.single faces any error it does not call next() instead it gets passed to next listner. To catch any error of upload.single you must add this after above app.post(/profile).
app.use(function (err, req, res, next) {
var error = err.message;
res.status(500);
res.send({ "error": error });
});

express next throwing error as next is not defined

I am trying to pass some predefined functions in the callback of app.post() method. I am getting next is not defined error. Below is my code. Please suggest where I am doing wrong or am I missing any concept here?
var express = require('express');
var app = express()
app.post('/api/signup', function(req, res) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
where I have each function defined and imported and returning next() after my process.
my validateParams function is below :
validateParams = function(req, res, next) {
console.log("at validator ", req);
next();
}
module.exports = validateParams;
my dbCall function is below :
dbCall = function(req, res, next) {
console.log("at dbCall ", req);
next();
}
module.exports = dbCall;
my sendResponse function is below :
sendResponse = function(req, res) {
console.log("at dbCall ", res);
res.send("Response sent successfully");
}
module.exports = sendResponse;
You probably forgot to add the next argument in your callback.
app.post('/api/signup', function(req, res, next) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
I think you are trying to use validateParams(req, res, next) and dbCall(req, res, next) as middleware functions. In this case, you need something like this:
const validateParams = (req, res, next) => {
// do stuff here
next();
}
const dbCall = (req, res, next) => {
// do stuff here
next();
}
app.post('/api/signup', validateParams, dbCall, function(req, res) {
sendResponse(req, res)
})
You can read more here

Express4 error middleware sequence

Came accros a sequence of code execution which I found unusual here is the code:
server.js
const Actions_Single_PVC = require('./routes/Actions_single_PVC.js');
app.use('/Actions_single_PVC', Actions_Single_PVC);
app.use((err, req, res, next) => {
console.log('invalid token');
});
Actions_single_PVC.js
router.post('/', asyncMW(async (req, res, next) => {
throw new Error();
}));
router.use((err, req, res, next) => {
console.log('error');
}
And in case you have never seen this construction before here is asyncMW:
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
module.exports = asyncMiddleware;
What I didn't understand was that when an error is thrown (I reproduced it here with throw new Error();) that the error handling middleware in the server.js file is executed. I expected that the error handling middleware of the Actions_single_PVC.js would get executed.
Question:
Why is the error middlware in server.js executed and not the error middlware in Actions_single_PVC.js?
It is because the following code applies middleware to only request with base path matching Actions_single_PVC.
app.use('/Actions_single_PVC', Actions_Single_PVC);
Whereas following code is apply middleware to all global requests.
app.use((err, req, res, next) => {
console.log('invalid token');
});
If you'll hit the url /Actions_single_PVC then the middlewares in Actions_single_PVC will get hit.

Node.js (Express) error handling middleware with router

Here's my application structure:
- app.js
- routes
---- index.js
The ExpressJS app creates error handlers for development and production environments. Here's a code snippet from app.js:
app.use('/', routes); // routing is handled by index.js in the routes folder
//The following middleware are generated when you create the Express App
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error.ejs', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
And inside of routes/index.js, where I handle all the routing:
var router = express.Router();
router.get('/', function (req, res) {
someAsyncFunction(function(err, result) {
if (err) throw err; // Handle this error
}
});
module.exports = router;
I want the err to be passed to one of the error handlers instead of being thrown. How can I do this?
You have to pass it to the next callback which is usually the third parameter in the route handler
var router = express.Router();
router.get('/', function (req, res, next) {
someAsyncFunction(function(err, result) {
if (err) {
next(err); // Handle this error
}
}
});
module.exports = router;
calling next(err) will allow the error to be caught in a middleware down the chain with the following signature:
app.use(function (err, req, res, next){
// do something about the err
});
Reference: http://expressjs.com/en/guide/error-handling.html
You can also create a middleware function to handle error in all routes without copying code everywhere, using arrow functions if you like.
1) Create a const function to handle errors.
either:
const handleErrorAsync = func => (req, res, next) => {
func(req, res, next).catch((error) => next(error));
};
or
const handleErrorAsync = func => async (req, res, next) => {
try {
await func(req, res, next);
} catch (error) {
next(error);
}
};
2) In your router use it for every request:
var router = express.Router();
router.get('/req1', handleErrorAsync(async (req, res, next) => {
let result = await someAsyncFunction1();
if(result){
// res.send whatever
}
}));
router.post('/req2', handleErrorAsync(async (req, res, next) => {
let result = await someAsyncFunction2(req.body.param1);
if(result){
// res.send whatever
}
}));
router.post('/req3', handleErrorAsync(async (req, res, next) => {
let result = await someAsyncFunction3(req.body.param1, req.body.param2);
if(result){
// res.send whatever
}
}));
module.exports = router;
3) In your server main app handle error:
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error.ejs', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
This way you can reuse the error handling function in any route. Also, if there are any unhandled errors in any of your functions, this will catch them as well.
Try catch error handling taken from Here

Express: How to factor routes callback

So I have multiple routes like this:
app.get('/user', function(req, res) {
model.find({}, function(err, docs) {
res.send(docs);
});
});
app.get('/user/:id', function(req, res) {
model.findById(req.params.id, function(err, doc) {
res.send(doc);
});
});
multiplied by a lot.
I'd like to know if they would be a way to factor out that callback function like that:
app.get('/user', function(req, res) {
model.find({}, sendInResponse);
});
app.get('/user/:id', function(req, res) {
model.findById(req.params.id, sendInResponse);
});
My problem is the res scope.
I would refactor it like this:
var find = function (queryFn) {
return function (req, res, next) {
var query = queryFn.apply({ req: req, res: res });
model.find(query, function (err, docs) {
res.send(docs);
});
}
};
Now you have generic query middleware which you can use like this:
app.get('/user/:id', find(function () { return { id: this.req.params.id } });
This is just the tip of what's possible and you can even refactor it more. This is a route from an app I created which uses only generic middleware:
app.get('/users/:username',
data.one('user', data_users.byUsername, 'params.username'),
data.many(data_grows.byUserId, 'locals.user.id'),
general.render('grows/index'));

Categories

Resources