1

I am relatively new in NodeJS and I'm learning from this tutorial series.

https://www.youtube.com/watch?v=49sWXJPk10Q&list=PLO-hrPk0zuI18xlF_480s6UiaGD7hBqJa&index=15

In this particular video, I get some errors after submitting the form. I have 2 doubts which searching in this site didn't get a clear answer. I hope you could give me more clarity.

1.In users.js, in line 32 it says profileimage in undefined, eventhough I have a file field with name profileimage.

2.If that line is changed to req.body.profileimage, that doesnt produce error, but I think it is still wrong. When submitting the form, nodeJS throws error

Error 'Can't set headers after they are sent'

I tried reading the other similar questions, but I couldn't relate this to my program(Because I haven't set any headers in my program explicitly). Please give more insight into these two problems.

var express = require('express');
var router = express.Router();


//var User = require('../models/user');
/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.get('/register', function(req, res, next) {
  res.render('register', {
      'title': "Register"
  });
});

router.get('/login', function(req, res, next) {
  res.render('login', {
      'title': "Login"
  });
});

router.post('/register', function(req, res, next) {
    //Get form values
    var name = req.body.name;
    var email = req.body.email;
    var password = req.body.password;
    var cpassword  = req.body.cpassword;


    //Check for image field
    if(req.files.profileimage) {
        console.log('Uploading File...');

        //File Info
        var profileImageOriginalName = req.files.profileimage.originalname;
        var profileImageName = req.files.profileimage.name;
        var profileImageMime = req.files.profileimage.mimetype;
        var profileImagePath = req.files.profileimage.path;
        var profileImageExt = req.files.profileimage.extension;
        var profileImageSize = req.files.profileimage.size;

    }
    else {
        var profileImageName = 'default.png';
    }

    //form validation
    req.checkBody('name','Name field is required').notEmpty();
    req.checkBody('email','Email field is required').notEmpty();
    req.checkBody('email','Enter a valid Email').isEmail();
    req.checkBody('password','Password field is required').notEmpty();
    req.checkBody('cpassword','Passwords fields do not match').equals(req.body.password);

    var errors = req.validationErrors();

    if(errors) {
        res.render('register', {
            errors: errors,
            name: name,
            email: email,
            password: password
        });
    }
    else {
        var newUser = new User({
            name: name,
            email: email,
            password: password,
            profileImage: profileImageName
        });
    }

*/
    //Success Message
    req.flash('success','You are now registered and may log in');

    res.location('/');
    res.redirect('/');

});

module.exports = router;

register.jade

extends layout

block content
  ul.errors
    if errors
      each error, i in errors
       li.alert.alert-danger #{error.msg}
  form.form-signin(method='post',action='/users/register',enctype='multipart/form-data')
      h2.form-signin-heading.text-center Register
      label.sr-only(for='inputName') Name
      input#inputName.form-control(name='name' type='text', placeholder='Name', autofocus='')
      label.sr-only(for='inputEmail') Email address
      input#inputEmail.form-control(name='email' type='email', placeholder='Email address')
      label.sr-only(for='inputPassword') Password
      input#inputPassword.form-control(name='password' type='password', placeholder='Password')
      label.sr-only(for='inputCPassword') Confirm Password
      input#inputCPassword.form-control(name='cpassword' type='password', placeholder='Confirm Password')
      label.sr-only(for='inputProfile') Profile Image
      input#inputProfile.form-control(name='profileimage' type='file')
      button.btn.btn-lg.btn-primary.btn-block(type='submit') Register

More detailed Error report

POST /users/register 500 91.651 ms - 2704<br>
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at ServerResponse.header (C:\Dev\nodeauth\node_modules\express\lib\response.
js:718:10)
    at ServerResponse.send (C:\Dev\nodeauth\node_modules\express\lib\response.js
:163:12)
    at done (C:\Dev\nodeauth\node_modules\express\lib\response.js:957:10)
    at Object.exports.renderFile (C:\Dev\nodeauth\node_modules\jade\lib\index.js
:374:12)
    at View.exports.__express [as engine] (C:\Dev\nodeauth\node_modules\jade\lib
\index.js:417:11)
    at View.render (C:\Dev\nodeauth\node_modules\express\lib\view.js:126:8)
    at tryRender (C:\Dev\nodeauth\node_modules\express\lib\application.js:639:10
)
    at EventEmitter.render (C:\Dev\nodeauth\node_modules\express\lib\application
.js:591:3)
    at ServerResponse.render (C:\Dev\nodeauth\node_modules\express\lib\response.
js:961:7)
    at C:\Dev\nodeauth\app.js:104:7
    at Layer.handle_error (C:\Dev\nodeauth\node_modules\express\lib\router\layer
.js:71:5)
    at trim_prefix (C:\Dev\nodeauth\node_modules\express\lib\router\index.js:310
:13)
    at C:\Dev\nodeauth\node_modules\express\lib\router\index.js:280:7
    at Function.process_params (C:\Dev\nodeauth\node_modules\express\lib\router\
index.js:330:12)
    at IncomingMessage.next (C:\Dev\nodeauth\node_modules\express\lib\router\ind
ex.js:271:10)
    at done (C:\Dev\nodeauth\node_modules\express\lib\response.js:956:25)
    at tryRender (C:\Dev\nodeauth\node_modules\express\lib\application.js:641:5)

    at EventEmitter.render (C:\Dev\nodeauth\node_modules\express\lib\application
.js:591:3)
    at ServerResponse.render (C:\Dev\nodeauth\node_modules\express\lib\response.
js:961:7)
    at C:\Dev\nodeauth\app.js:93:9
    at Layer.handle_error (C:\Dev\nodeauth\node_modules\express\lib\router\layer
.js:71:5)
AshTyson
  • 473
  • 7
  • 23
  • 2
    You can find the solution here -http://stackoverflow.com/questions/7042340/node-js-error-cant-set-headers-after-they-are-sent – Ahtisham May 16 '16 at 10:31
  • I don't see how it is relevant. Because I haven't called any function after res.sendRedirect. What might've triggered the error after the redirect? I followed the tutorial line by line. Do I have to take some node update into account? – AshTyson May 16 '16 at 11:17
  • Where do you import the router? Some kind of `app.js`/`server.js` where you create the express app? Maybe the request object is modified there, before you pass it down to the router. – Scarysize May 16 '16 at 11:29
  • I searched the app.js as well the current user.js there is no implicit call to res.sendRedirect or res.setHeader. What could I do next? – AshTyson May 16 '16 at 11:58
  • What happens at that line? `at C:\Dev\nodeauth\app.js:104:7` – Nicole May 16 '16 at 13:44

1 Answers1

2

You need to move this code:

//Success Message
req.flash('success','You are now registered and may log in');

res.location('/');
res.redirect('/');

It should be inside of the conditional:

else {
        var newUser = new User({
            name: name,
            email: email,
            password: password,
            profileImage: profileImageName
        });
        //Success Message
        req.flash('success','You are now registered and may log in');

        res.location('/');
        res.redirect('/');
    }

What happens if you have it outside and you get an error is this. First your if-statement fires:

if(errors) {
    res.render('register', {
        errors: errors,
        name: name,
        email: email,
        password: password
    });
}

When res.render is called the response is Finished and the headers are sent. However: Since you have the res.redirect and res.location outside of the conditional Express tries to run this too. And that is why you get the error message.

Also as was pointed out in a comment on your question you can read more here.

Community
  • 1
  • 1
tomtom
  • 642
  • 7
  • 12