AngularJS - PUT method not working (404 error)

10,823

After reading more carefully, the problem is indeed that you don't send the id in the url when you do the update request. Furthermore, the way you call update / save is not quite what is intended with resource. After you have created a resource, you call the save / update methods on the instance, not as a factory function. You can also bind properties of the instance to the params in the url, so you don't have to specify them on each call:

AppServices.factory('appFactory', function($resource) {
  return $resource('/api/main/actions/:actionid', {actionid : '@actionid'}, {
    'update': { method: 'PUT'},
});

The second parameter of resource tells angular which properties it should use to populate the url parameters. so the get operation stays the same:

$scope.action = appFactory.get({actionid: $routeParams.actionid});

and the update is now:

$scope.submitAction = function() {
  // UPDATE CASE
  if ($scope.action.actionid > 0) {
    $scope.action.$update()
  } else {
    $scope.action.$save();  
  }
}

Since you used angular-cellar as a basis, I should probably check and see if I can improve this ...

Share:
10,823
claire_
Author by

claire_

Updated on June 14, 2022

Comments

  • claire_
    claire_ almost 2 years

    I'm new to AngularJS and I have trouble to update an object via REST. I'm using a PHP/Mysql Backend (Slim Framework).
    I'm able to retrieve (GET), create (POST) a new object but not to edit (PUT) one. Here's the code:

    my Form:

    <form name="actionForm" novalidate ng-submit="submitAction();">
      Name: <input type="text" ng-model="action.name" name="name" required>
      <input type="submit">
    </form>
    

    My service:

    var AppServices = angular.module('AppServices', ['ngResource'])
    AppServices.factory('appFactory', function($resource) {
      return $resource('/api/main/actions/:actionid', {}, {
        'update': { method: 'PUT'},
      });
    });
    

    app.js

    var app = angular.module('app', ['AppServices'])
    app.config(function($routeProvider) {
      $routeProvider.when('/main/actions', {
        templateUrl: 'partials/main.html',
        controller: 'ActionListCtrl'
      });
      $routeProvider.when('/main/actions/:actionid', {
        templateUrl: 'partials/main.html',
        controller: 'ActionDetailCtrl'
      });
      $routeProvider.otherwise({redirectTo: '/main/actions'});
    });
    

    controllers.js:

    function ActionDetailCtrl($scope, $routeParams, appFactory, $location) {
      $scope.action = appFactory.get({actionid: $routeParams.actionid});
      $scope.addAction = function() {
        $location.path("/main/actions/new");
      }
      $scope.submitAction = function() {
        // UPDATE CASE
        if ($scope.action.actionid > 0) {
          $scope.action = appFactory.update($scope.action);
          alert('Action "' + $scope.action.title + '" updated');
        } else {
          // CREATE CASE
          $scope.action = appFactory.save($scope.action);
          alert('Action "' + $scope.action.title + '" created');
        }
        $location.path("/main/actions");
      }
    }
    

    In Slim, in api/index.php, I've got these routes and functions defined:

    $app->get('/main/actions', 'getActions');
    $app->get('/main/actions/:actionid',    'getAction');
    $app->post('/main/actions', 'addAction');
    $app->put('/main/actions/:actionid', 'updateAction');
    

    When I create a new "action", everything is working as expected. But when I try to edit an existing one, I've got this error:

    PUT http://project.local/api/main/actions 404 Not Found

    The action is not updated (although the alert message "Action xxx updated" is displayed)

    Is it an issue with my routeProvider setting ? I guess the PUT url misses the id at the end...

    I precise that if I try to simulate the PUT request with POSTMan-Chrome-Extension for example, everything is working well (PUT http://project.local/api/main/actions/3 returns the expected data)

  • claire_
    claire_ almost 11 years
    Thanks again for your time, your explanation is perfectly clear.
  • Nik
    Nik about 10 years
    In order to get this to work, I needed to call the update using the id parameter, similar to the get: $scope.action.$update({actionid: $routeParams.actionid}). If not, the server would return a 404 since it's expecting an id in the path.
  • fsalazar_sch
    fsalazar_sch over 8 years
    I have the same problem, but, still getting error 404