0

I'm new to the MEAN stack, trying basic apps with tutorials. Getting user input from a registration form using Angular. Password getting encrypted using bcrypt. When I log the user object that is being sent from the registration form, in the front-end the object has all the appropriate data. Posting using $http.post() method. Once the object is received in the back-end controller, all the fields say 'undefined'.

I saw that a couple of people have previously discussed this same error and the only conclusion that everyone arrived at, was that the bcrypt.hashSync() function wasn't receiving the password or receiving it as undefined. How do I solve the problem of the function receiving it as "undefined"? Please help.

backend app.js file -

require('./api/data/db.js');
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
var routes = require('./api/routes');

app.set('port',3000); //Defining port

app.use(function(req, res, next){
  console.log(req.method, req.url);
  next();
});

app.use(express.static(path.join(__dirname, 'public'))); // Delivering static files from public folder
app.use('/node_modules', express.static(__dirname+'/node_modules'));
app.use(bodyParser.urlencoded({ extended : false }));

app.use('/api',routes);

//Setting the port to listen to requests
var server = app.listen(app.get('port'), function(){
  var port = server.address().port; //Extract port number fromserver object
  console.log("App running. Port number - " + port);
});

register controller function (node.js backend) -

module.exports.register = function(req, res){
console.log("Registering Users");
console.log(req.body.email);
console.log(req.body.fname);
console.log(req.body.lname);
console.log(req.body.password);
var email = req.body.email;
var fname = req.body.fname;
var lname = req.body.lname;
var password = req.body.password;

User.create(
  {
    email: email,
    fname: fname,
    lname: lname,
    password: bcrypt.hashSync(password, bcrypt.genSaltSync(10))
  }, function(err, user){
    if(err){
      console.log(err);
      res
        .status(400)
        .json(err);
    } else {
      console.log("User created", user);
      res
        .status(201)
        .json(user);
    }
  }
);
};

register controller function (angular.js front-end) -

function RegisterController($http){
var vm = this;

vm.register = function(){
var user = {
  email: vm.email,
  fname: vm.fname,
  lname: vm.lname,
  password: vm.password
};

if(!vm.email || !vm.password){
  vm.error = 'Please enter an email and password.';
} else {
  if(vm.password !== vm.passwordRepeat){
    vm.error = 'Please enter matching passwords.';
  } else {
    console.log(user);
    $http.post('/api/users/register', user).then(function(result){
      console.log(result);
      console.log(user);
      vm.message = 'Successful registration! Please login.';
      vm.error= '';
    }).catch(function(error){
      console.log(error);
    });
  }
}
}
};

Node file with routing -

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


var ctrlUsers = require('../controllers/users.controller.js');

router
  .route('/users/register')
  .post(ctrlUsers.register);

module.exports = router;

HTML -

<h1>Register</h1>

<div ng-if="vm.message" class="alert alert-success" role="alert">
  <p>{{ vm.message }}</p>
</div>

<div ng-if="vm.error" class="alert alert-danger" role="alert">
  <p>{{ vm.error }}</p>
</div>

<form ng-hide="vm.message" name="register" ng-submit="vm.register()">
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email" class="form-control" id="email" placeholder="Enter Email" ng-model="vm.email" autocapitalize="none">
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" class="form-control" id="password" placeholder="Enter password" ng-model="vm.password" autocapitalize="none">
  </div>

...some more elements...

<button type="submit" class="btn btn-success">Register</button>

</form>

console:

GET /angular-app/app.js
GET /angular-app/register/register-controller.js
GET /angular-app/register/register.html
POST /api/users/register
Registering Users
undefined
undefined
undefined
undefined
Error: data and salt arguments required
arjunkm
  • 471
  • 6
  • 12

2 Answers2

0

Can you try the below code. I have not tried running this but hope it gives an idea. Also try using ng-click in html

function RegisterController($http, $scope){
    $scope.vm = {};

    $scope.register = function() {
       var user = {
      email: $scope.vm.email,
      fname: $scope.vm.fname,
      lname: $scope.vm.lname,
      password: $scope.vm.password
    };

    if(!$scope.vm.email || !$scope.vm.password){
      vm.error = 'Please enter an email and password.';
    } else {
      if($scope.vm.password !== $scope.vm.passwordRepeat){
        $scope.vm.error = 'Please enter matching passwords.';
      } else {
        console.log(user);
        $http.post('/api/users/register', user).then(function(result){
          console.log(result);
          console.log(user);
          $scope.vm.message = 'Successful registration! Please login.';
          $scope.vm.error= '';
        }).catch(function(error){
          console.log(error);
        });
      }
    }
    }
    };
vizsatiz
  • 1,933
  • 1
  • 17
  • 36
  • Got an error in the console - angular.js:13642 ReferenceError: $scope is not defined – arjunkm Jul 08 '18 at 11:09
  • angular.js:13642 ReferenceError: $scope is not defined at new RegisterController (http://localhost:3000/angular-app/register/register-controller.js:4:3) – arjunkm Jul 08 '18 at 11:12
  • `function RegisterController($http, $scope)` is this how you defined – vizsatiz Jul 08 '18 at 11:15
  • My bad, I'd forgotten the $scope in that line. So the error is now not appearing anymore, but nothing is happening after the submit button is pressed. It's almost like no functionality has been added to the button. – arjunkm Jul 08 '18 at 11:32
  • Did you use `ng-click` on the button? – vizsatiz Jul 08 '18 at 11:33
  • I used ng-submit="vm.register()" in the form element. If I undo the $scope edit, submit button works but I get back the same 500 Internal Server error and the things mentioned above in the question. :/ – arjunkm Jul 08 '18 at 11:39
0

The problem is that your server accepts the posted data in this format:

 username=jonas&password=test

But the default setting of $.post sends it as json:

{ "username": "jonas", "password": "test" }

To resolve this, either change the data $.post sends, or you change the servers bodyparser from urlencoded to json:

app.use(bodyParser.json());

how [did] you realized that would work?

As you logged the user object on the clientside, I assumed that you checked that the data was sent correctly, and your route seemed correct. So the error had to be somewhere on the way between the $.post call and the data reaching the route. As you mounted the routes correctly, the only mistake that was left was a missmatch in the encoding of the body.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151