Search code examples
javascriptangularjsrestangular

Editing a model with Restangular in Angular is breaking the PUT because Restangular is appending the model ID


I'm trying to create an edit view for my Angular App. I'm using Restangular as the service for handeling my CRUD operations.

The Plunker here is a great example: http://plnkr.co/edit/d6yDka?p=preview&codekitCB=406920728.784061

But I'm not going to use resolve. I wasn't abel to get the promise to pass to the controller.

No big deal though, I just do my single get in the controller like I would for a detail view.

The form fields populate nicely. However, when I do the PUT to save the edit, It appends the model ID to the URL so that it effectively does the following: /api/tasks/33/33. How do I get it to NOT append the id of the model onto the path that the PUT is sending the data to?

I would think that I could override the .put() with something like .put('tasks/' + $routeParams.taskId). But that's not working. Of course, that assumes that the Restangular root_api is set at /api/ which it is. But that gives me a 404 error as it tries to split the content of .put("tasks/" + $routeProvider.taskId) and then appends that to the url for teh API.

So, how do I get Restangular to stop appending the ID to the URL? Or, how do I do this the right way if I'm doing something wrong?

Here's my code for reference.

var myApp = angular.module('myApp', [
    'ngRoute',
    'ngAnimate',
    'restangular',
    'myAppControllers'
]);

myApp.config(
    function($routeProvider, RestangularProvider) {
        $routeProvider.
            when('/tasks/edit/:taskId', {
                templateUrl: '/static/partials/task-edit.html',
                controller: 'TaskEditCtrl'
            }).
            otherwise({
                redirectTo: '/tasks'
            });

            RestangularProvider.setBaseUrl('/api/');
            RestangularProvider.setParentless(true);
            RestangularProvider.setDefaultHttpFields({xsrfCookieName:'csrftoken', xsrfHeaderName:'X-CSRFToken'});
});

var myAppControllers = angular.module('myAppControllers', [
    'restangular'
]);

myAppControllers.controller('TaskEditCtrl', ['$scope', 'Restangular',

    function($scope, Restangular) {

        $scope.successMessage = true;

        Restangular.one("tasks/" + $routeParams.taskId).get().then(function(task){
            $scope.task = task;
        })

        var original = task;

        $scope.task = Restangular.copy(original);

        $scope.isClean = function() {
            return angular.equals(original, $scope.task);
        }

        $scope.save = function() {
            $scope.task.put().then(function(task) {
                $scope.successMessage = false;
            });
            console.log('saved');
        }
    }

]);

Solution

  • Instead of calling Restangular.one('tasks/' + <id>), what you really meant to do was Restangular.one('tasks', <id>). That way Restangular knows that the route is really tasks and not tasks/<id>.