3

I have angularjs application which have CRUD Rest service. Create, Read and Delete methods works well, but PUT not works. I found on Stackoverflow and there are the same problems with accepted answers e.g.:

Angular JS: Full example of GET/POST/DELETE/PUT client for a REST/CRUD backend?

AngularJS - PUT method not working (404 error)

So I do it like in this answers but my update (by PUT method) not works (Status code: 404 'Cannot PUT /api/adverts'). Maybe folks notice something in my code. One important thing is that I use angular 1.0.8

services.js (angularjs):

var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);

motoAdsServices.factory('Advert', ['$resource', function($resource) {
    return $resource('/api/adverts/:advertId', {}, {
       update: {method:'PUT', params: {advertId: '@advertId'}}
    });
  }]);

editAdvert.html

  <label class="control-label">Brand</label>
  <div class="controls">
    <select name="brand" ng-model="editAdvert.brand" required ng-options="b.name for b in brands">
      <option value=""></option>
    </select>
  </div>

  <label class="control-label">Model</label>
  <div class="controls">
    <select name="model" ng-model="editAdvert.model" required ng-options="m.name for m in editAdvert.brand.models">
      <option value=""></option>
    </select>
  </div>

controllers.js (angular.js - I removed no significant code):

$scope.updateAdvert = function() {
  var editAdvert = {
    _id: $scope.editAdvert._id,
    brandName: $scope.editAdvert.brand.name,
    modelName: $scope.editAdvert.model.name,
    year: $scope.editAdvert.year,
    price: $scope.editAdvert.price,
    imageUrl: $scope.editAdvert.imageUrl,
    countryName: $scope.editAdvert.country.name,
    regionName: $scope.editAdvert.region.name
  };

  // !!! I TRY THIS TO FIX !!!
  $scope.advertId = $scope.editAdvert._id;

  // !!! THIS NOT WORKS STILL !!!
  Advert.update(editAdvert, function() {
    previousAdvert = angular.copy($scope.editAdvert);
    alert('Advert updated');
  });
};

server.js (nodejs):

var express = require('express');
var path = require('path');
var http = require('http');
var adverts = require('./routes/adverts');

var app = express();

app.configure(function() {
  app.set('port', process.env.PORT || 3000);
  app.use(express.logger('dev'));  /* 'default', 'short', 'tiny', 'dev' */
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.static(path.join(__dirname, 'public')));
});

app.get('/api/adverts', adverts.findAll);
app.get('/api/adverts/:id', adverts.findById);
app.post('/api/adverts', adverts.add);
app.put('/api/adverts/:id', adverts.update);
app.delete('/api/adverts/:id', adverts.remove);

http.createServer(app).listen(app.get('port'), function() {
  console.log("Express server listening on port " + app.get('port'));
});

In response I get 404 and 'Cannot PUT /api/adverts'. I'm almost convinced that it is the problem of lack '_id' at the end of URL. See the picture: enter image description here

Please look at my code and give some suggestion.

Community
  • 1
  • 1
lukpaw
  • 1,603
  • 2
  • 26
  • 31

1 Answers1

3

I see some inconsistencies here. Firstly, the update should be the instance method. So the call should be like this: $scope.editAdvert.$update(... instead of Advert.update($scope.editAdvert...

Another thing here is the difference in the argument names. The resource is instructed, that the id of the resource should be advertId, while, as the picture shows, the object has id named _id

And finally, you are setting $scope.advertId = $scope.editAdvert._id; ... as you say to fix it. The problem is, that it is not related to the object $scope.editAdvert ... it just another object of the $scope. The Resource is not aware of it.

See more details about the ngResource here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • 1
    Thanks! 1. `update` isn't the instance method because `var editAdvert` (it has `brandName` simple string) which I put to `Advert.update` is other than `$scope.editAdvert` (i has `brand` complex object). I use $scope.Advert in editAdvert.html to work with select (see the code - I updated to show you). 2. It's perfect suggestion I change my code to `update: {method:'PUT', params: {advertId: '@_id'}}` and it WORKS! 3. I remove my fix. If you can look at my updated code `controllers.js` and `editAdvert.html` and check now inconsistencies. – lukpaw Nov 16 '13 at 18:07
  • 1
    Of course the FIX line is removed and I changed in services.js `update: {method:'PUT', params: {advertId: '@_id'}}` – lukpaw Nov 16 '13 at 18:17
  • Great to see that ;) Enjoy Angular – Radim Köhler Nov 16 '13 at 18:23