Search code examples
angularjsrestangularrestheart

Issues Angular Restangular save and update operations


I decided to take my project in the Restangular, but I have some problems in the SAVE and UPDATE operations.

I use the API restheart with mongodb.

In SAVE in my case, I'm saving a New Post, and when by chance I make any changes, it saves a new post out instead of updating it.

UPDATE on, I can update the first instance, for example, make a change in title and saved, it updated if I update again .. generates this error:

PUT http://127.0.0.1:8080/api/portfolio/55ef4b15ef862e8f7316cbf1 412 (Precondition Failed) Follow my resource and code:

Restangular.all($scope.section).getList($scope.query).then(function(res){
    $scope.items = res;
});

my SAVE:

// create new object item
$scope.item = Restangular.one($scope.section);

// save object
$scope.addItem = function(){
    $scope.item.save().then(function(){
            toast.msgToast($scope.section + ' ...item criado!');
    }, function(err){
        toast.msgToast($scope.section + ' ...ocorreu um erro ao criar o item!');
    });
};

my UPDATE:

$scope.updateItem = function(){
        $scope.item.save().then(function(){
            toast.msgToast($scope.section+ ' #' +$scope.item._id.$oid+ ' ....Atualizado!');
        });
    };

    $scope.loadItem = function(){
        Restangular.one($scope.section, $stateParams.id).get().then(function(item) {
            $scope.item = item;
        });
    };

Solution

  • In RESTHeart, POST and PUT are upsert operations, i.e. they create a resource if it does not exist or updates it.

    The point here is about the _id:

    • In PUT operations, the document id is given by the URI /db/collection/id_of_document (more information on URI format in the official documentation here)
    • In POST operations, the _id property can be specified in the json payload. If it is not specified, a new document gets created and the automatically generated _id (of type ObjectId) is returned via the Location response header. If the _id is specified, the POST will result in an update given that a document with that _id already exists.

    In your case, on fist POST (that creates the document), you need to get the Location response header with the URI of the created post resource and reload it via a GET operation; further POST with this data (that now contains the generated _id) will result in an update.

    In any case, when your are doing a POST, PATCH, PUT or DELETE operation on an existing resource, you need to pass the ETag via the If-Match request header. You can find more information in the ETag section of the official documentation, including an example with AngularJs.

    More, there is a complete example of a web application using RESTHeart, AngluarJs and Restangular on github: restheart-notes-example.

    Have a look at the notes.js controller, where you'll find all the logic to create, update and delete documents.