mysqlangularjsnode.jsloopbackjsstrongloop

POST request returns 422 (unprocessable entity)


I have an AngularJS app that is using node.js and Loopbackjs to communicate with a mysql database. I am able to properly show my GET request on the partial-home.html aspect of the page, but when I create a new user it returns the following error:

POST http://localhost:3000/api/se_users 422 (Unprocessable Entity)

Here is my code:

partial-create.html

<div class="row">
    <div class="col-md-8">
        <h1>Create a User</h1>
    </div>
</div>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form name="create" ng-submit="se_user()">
                <div class="form-group">
                    <label for="user_id">ID</label>
                    <input type="text" class="form-control" ng-model="user.eid" placeholder="Enter EID">
                </div>
                <div class="form-group">
                    <label for="first_nm">First Name</label>
                    <input type="text" class="form-control" ng-model="user.first_nm" placeholder="Enter First Name">
                </div>
                <div class="form-group">
                    <label for="last_nm">Last Name</label>
                    <input type="text" class="form-control" ng-model="user.last_nm" placeholder="Enter Last Name">
                </div>
                <div class="form-group">
                    <label for="email_adr">Email Address</label>
                    <input type="text" class="form-control" ng-model="user.email_adr" placeholder="Enter Item Type">
                </div>
                <div class="form-group">
                    <label for="user_role">Role</label>
                    <input type="text" class="form-control" ng-model="user.role" placeholder="Enter Status Code">
                </div>
                <div class="form-group">
                    <label for="user_active">Active</label>
                    <div class="radio">
                        <label>
                            <input type="radio" name="optionsRadios" id="optionsRadios1" value="Yes" ng-model="user.active" checked>Yes
                        </label>
                    </div>
                    <div class="radio">
                        <label>
                            <input type="radio" name="optionsRadios" id="optionsRadios2" value="No" ng-model="user.active">No
                        </label>
                    </div>
                </div>
                <div class="form-group">
                    <label for="mgr_full_nm">Manager Name</label>
                    <input type="text" class="form-control" ng-model="user.mgr_full_nm" placeholder="Enter Full Name">
                </div>
                <div class="form-group">
                    <label for="mgr_eid">Manager EID</label>
                    <input type="text" class="form-control focus" ng-model="user.mgr_eid" placeholder="Enter Manager EID">
                </div>
                <div class="form-group">
                    <label for="insrt_dt">Insert Date</label>
                    <input type="date" class="form-control" ng-model="user.insrt_dt" placeholder="Enter Date">
                </div>
                <div class="form-group">
                    <label for="insrt_user_id">Insert User EID</label>
                    <input type="text" class="form-control" ng-model="user.insrt_user_id" placeholder="Enter User EID">
                </div>
                <div class="form-group">
                    <label for="upd_dt">Update Date</label>
                    <input type="date" class="form-control" ng-model="user.upd_dt" placeholder="Enter Update User Date">
                </div>
                <div class="form-group">
                    <label for="upd_user_id">Update User EID</label>
                    <input type="text" class="form-control" ng-model="user.upd_user_id" placeholder="Enter Update User EID">
                </div>


                <button class="btn btn-primary btn-lg" ng-click="addSe_user()">Create User</button>

                <br>
                <br>
                <pre>
        {{user | json}}
        </pre>

            </form>
        </div>
    </div>
</div>

app.js

angular.module('userApp', ['ui.router', 'lbServices'])

.controller('UserController', ['$scope', '$state', 'Se_user', function ($scope, $state, Se_user) {
    $scope.users = [];

    function getSe_users() {
        Se_user
            .find()
            .$promise
            .then(function (results) {
                $scope.users = results;
            });
    }
    getSe_users();

    $scope.addSe_user = function () {
            Se_user
            .create($scope.user);
            alert('You have created a new user!')
            $scope.create.$setPristine();

        };

    $scope.editSe_user = function(user_id) {
        Se_user
            .editById(user_id)
            .$promise
            .then(function (user_id) {
                getSe_users();
        });
    };

    $scope.removeUser = function (item) {
        Se_user
            .deleteById(item)
            .$promise
            .then(function () {
                getSe_users();
            });
    };
}])

.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('');

    $stateProvider

        .state('home', {
            url: '',
            templateUrl: 'partial-home.html',
            controller: 'UserController'
        })
        .state('create', {
            url: '/create',
            templateUrl: 'partial-create.html',
            controller: 'UserController'
        })
    .state('admin', {
        url: '/admin',
        templateUrl: 'partial-admin.html',
        contoller: 'UserController'
    })

}]);

Solution

  • Change your create line from

    Se_user
    .create($scope.user);
    

    to

    Se_user
    .create($scope.user, 
      function(newUser) {
        console.log(newUser);
        // only set pristine here, this
        // callback fires on success
        $scope.create.$setPristine();
      },
      function(err) {
        console.log(err); // will log the error to the console
      }
    
    );
    

    The alert shouldn't get in the way of seeing the dev tools output, but this structure makes it easier to get the error response by using the error callback in the call.

    The way you have it, the alert that says you have created a new user will fire immediately after the ajax call to create the new user is sent—not received. There will be some delay for the server to respond so any code you write that depends on the new user being created (or erroring) needs to go inside the callback to the .create() method.

    See the Loopback Angular $resource docs here: https://docs.strongloop.com/display/public/LB/AngularJS+JavaScript+SDK#AngularJSJavaScriptSDK-ModelresourceAPI

    UPDATE: Chrome console - you should see a stack trace with your 422 error when you inspect the Network call in Chrome Dev tools, like this 401 error:

    enter image description here

    Please edit your original question and post the full text of that trace into it as a code block.