Why returning Undefined?

404 views Asked by At

I am working on a app where I am using Hapijs/Nodejs with AngularJS

here is the Nodejs part

server.route({
  method: 'POST',
  path: '/login',
  handler: function(request, reply) {
    USER: request.payload.user,
    PWD: request.payload.password,
    PLANTA: request.payload.planta,
    PLANGROUP: request.payload.plantgroup,
    START_DATE: request.payload.startDate
  }
});

now the Angular part

  .factory('LoginService', function($http, $q) {

    var defer = $q.defer();

    return {
      login: function() {
        $http.post('http://localhost:8000/login', {
          user: 'USRCP_HW',
          password: 'usrcp2012',
          planta: '6000',
          plantroup: 'E10',
          startDate: '2014-11-26'
        }).success(function(data) {
          console.log(data);
          return data;
        }).error(function(data, status){
          console.log(data, status);
          defer.reject(data);
        });
        return defer.promise;
      }
    }

  });

and the Login Controller

  .controller('LoginCtrl', function($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function(data) {
      console.log(data);
    };

  });

all I need is to log the data, but I am getting undefined.

and if in the controller I do

$scope.login = function(data) {
  console.log(data);
  LoginService.login(data).then(function() {
    console.log(data);
  })
};

I get this in the browser console

OPTIONS http://localhost:8000/login

XMLHttpRequest cannot load http://localhost:8000/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 501.

4

There are 4 answers

2
Arun P Johny On BEST ANSWER

The error is because of the same origin policy constrains, I think you can use relative path for the login url.

You can't return from an asynchronous method like that

.factory('LoginService', function ($http, $q) {

    var defer = $q.defer();

    return {
        login: function () {
            $http.post('/login', {
                user: 'USRCP_HW',
                password: 'usrcp2012',
                planta: '6000',
                plantroup: 'E10',
                startDate: '2014-11-26'
            }).success(function (data) {
                console.log(data);
                defer.resolve(data); //resolve the promise
                //you can't return from here as it is executed asynchronosly
            }).error(function (data, status) {
                console.log(data, status);
                defer.reject(data);
            });
            return defer.promise;
        }
    }

});

then

.controller('LoginCtrl', function ($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function (data) {
        console.log(data);
    };

    LoginService.login().then($scope.login)

});

Also there is no need to create a custom promise as $http also returns one

.factory('LoginService', function ($http, $q) {

    return {
        login: function () {
            return $http.post('http://localhost:8000/login', {
                user: 'USRCP_HW',
                password: 'usrcp2012',
                planta: '6000',
                plantroup: 'E10',
                startDate: '2014-11-26'
            }).success(function (data) {
                console.log(data);
                //you can't return from here as it is executed asynchronosly
            }).error(function (data, status) {
                console.log(data, status);
            });
        }
    }

});

then

.controller('LoginCtrl', function ($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function (data) {
        console.log(data);
    };

    LoginService.login().success($scope.login)

});
0
James Wong On

You are running into a cross-origin resource problem. If you are opening the website from http://127.0.0.1 then your script has to load/ post resources to 127.0.0.1 and not localhost as you doing in the login function.

Also if you are using an Apache web server, you can add this to your .htaccess file:

Header set Access-Control-Allow-Origin "*"

More reading here:

0
Karanvir Kang On

Replace http://localhost:8000/login with /login if the site on which this script is running is also hosted on http://localhost:8000.

Otherwise, you have to add cross-origin policy on your NodeJs server:

app.all('*', function(req, res, next) {
       res.header("Access-Control-Allow-Origin", "*");
       next();
});

P.S: The instructions to allow CORS might be different depending on your flavor of web server.

0
Clarkie On

Going back to your original question about CORS... In Hapi you can configure this on a route by route basis or on a global basis.

var server = new Hapi.Server();

server.connection({
    port: process.env.PORT || 3333, 
    routes: { 
        cors: true 
    } 
});

You can find more info here: http://hapijs.com/api#route-options

Alternatively you can serve both the client and the api from the same domain as suggested by Karanvir Kang