John foo
John foo

Reputation: 45

How can I get the response of a POST request using Angular JS?

I am using node, express, mongoose for backend and angular js for front-end. I am sending a post request using a form.

<div class="alert alert-success" ng-show="success">
  {{success}}
</div>

<div class="alert alert-danger" ng-show="error">
  {{error}}
</div>

  <form id="newCategory" ng-submit="submit()">
    <div class="row">
      <div class="col-md-4">
        {{mySubmit}}
        <div class="form-group">
          <input id="name" name="name" type="text"
            placeholder="Name" class="form-control input-md"
            ng-model="catName">
        </div><!-- ./form-group -->

      </div><!-- ./col -->

      <div class="form-group">
       <input type="submit" name="submit" value="submit" class="btn btn-primary">
      </div><!-- ./form-group -->

    </div><!-- ./row -->
  </form>

Its controller:

  fetchModule.controller('CatsNewCtrl', ['$scope', '$rootScope', 'Request',
    function($scope, $rootScope, Request) {
      // Root Scope
      $rootScope.heading  = 'Categories';
      $rootScope.heading2 = 'new';
      $rootScope.newLink  = undefined;

      $scope.catName = "";
      $scope.submit = function() {
        Request.post('/category', { name  : $scope.catName })
          .then(function(data) {
            $scope.success = data.msg;
          })
          .catch(function(status) {
            $scope.error = "Error: " + status;
          });
        return false;
      };
  }]);

Result is nothing, I don't know where am I going wrong! This service is working fine in fact I was able to console log the result but I am unable to set it on scope.

(function() {
  let fetchModule = angular.module('fetchModule', []);

  /**
   * A Service for Requests.
   */
  fetchModule.service('Request', ['$http', function($http) {
    /**
     * Get's content of a specific URL.
     * @param {String} url - URL to GET.
     * @return {Promise} Promise resolves with contents or rejects with an error.
     */
    this.get = function(url) {
      // Promise
      return new Promise((resolve, reject) => {
        $http.get(url)
          .success(result => {
            resolve(result);
          })
          .error((err, status) => {
            reject(err);
          });
      });
    };

/**
 * Get's content of a specific URL.
 * @param {String} url - URL to GET.
 * @param {String} data - Data to post.
 * @return {Promise} Promise resolves with contents or rejects with an error.
 */
this.post = function(url, data) {
  // Promise
  return new Promise((resolve, reject) => {
    $http.post(url, data)
      .success((data, status, headers, config) => {
        resolve(data);
      })
      .error((data, status, headers, config) => {
        resolve(status);
      });
  });
};

Please help I am just an angular starter.

Upvotes: 0

Views: 114

Answers (2)

Taner Melikoglu
Taner Melikoglu

Reputation: 114

    scope.submit = function() {
    $http({
      url:'/category', 
      method:'POST'
      data:{ name  : $scope.catName },
      headers: {'Content-Type': 'application/json'},
     })
      .then(function(resp) {
        $scope.success = resp.data.msg;
      },function(error){
        $scope.error = "Error: " + err.status;}
      )};

Don't return false, because it is a callback function. Instead of using catch block use "function-block" like above.

I have improved the solution. If it works, can you refactore it to move reused code to your service. Dont miss to inject $http in your controller.

Upvotes: 0

charlietfl
charlietfl

Reputation: 171669

You are using an anti-pattern wrapping $http in Promise since $http itself returns a promise.

In addition, since global Promise is outside of angular context, whenever it changes the scope angular needs to be notified to run a digest to update the view. Using angular promises this is not the case.

Change Request.post to:

this.post = function(url, data) {  
  return $http.post(url, data);
};

In controller there is a minor difference in that the object returned holds the data from server in a property data

$scope.submit = function() {
    Request.post('/category', { name  : $scope.catName })
      .then(function(resp) {
        $scope.success = resp.data.msg;
      })
      .catch(function(err) {
        $scope.error = "Error: " + err.status;
      });
    return false;
  };

Note that $http methods .success() and .error() are deprecated

Upvotes: 2

Related Questions