-1

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.

Non
  • 8,409
  • 20
  • 71
  • 123

4 Answers4

1

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)

});
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • I am getting this: ```TypeError: LoginService.login(...).success is not a function``` – Non Jun 18 '15 at 02:51
  • @ArunPJohny - if you don't throw the exception from the .error handler - if login throws an error - you won't be able to handle the error in the next .error handler - you loose chainability. The `data` should also be returned from the success handler right ? Otherwise it doesn't end up in the $scope.login function – sirrocco Jun 18 '15 at 03:32
1

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

Clarkie
  • 7,490
  • 9
  • 39
  • 53
0

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:

James Wong
  • 4,529
  • 4
  • 48
  • 65
0

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.

Karanvir Kang
  • 2,179
  • 19
  • 16