restangular icon indicating copy to clipboard operation
restangular copied to clipboard

PUT not putting changes when model is get through $object

Open windevalley opened this issue 11 years ago • 24 comments

restanglar v1.3.1

$scope.data = Restangular.one("collection", "1245").get().$object;
// I got back

{ 
  title: "some title"
}

$scope.data.title = "title 123";
$scope.data.put();

It will not put the changes.

But if get through promise it will work.

Restangular.one("collection", "1245").get().then(function(result) {
  $scope.data = result;
});
$scope.data.title = "title 123";
$scope.data.put(); // will work

windevalley avatar Feb 18 '14 04:02 windevalley

Hey,

Thanks for the report!

Can you provide a plunkr or jsfiddle with an example?

You can use http://angularjstalk.apiary.io/movies API as an example.

mgonto avatar Feb 18 '14 04:02 mgonto

I make a jsfiddle http://jsfiddle.net/jAy4n/

but http://angularjstalk.apiary.io/movies don't accept /GET http://angularjstalk.apiary.io/movies/1 and http://angularjstalk.apiary.io/directors/1 don't accept /PUT http://angularjstalk.apiary.io/directors/1

So the jsfiddle is incomplete.

windevalley avatar Feb 24 '14 11:02 windevalley

I also faced same issue and created an example at http://jsfiddle.net/merlinran/8fvGh/ Same if I change put() to post().

http://jsonplaceholder.typicode.com/ is a great API for test.

merlinran avatar Mar 13 '14 16:03 merlinran

Can this please get bumped? It's kind of a big bug.

jondthompson avatar Oct 23 '14 16:10 jondthompson

+1

Quji avatar Oct 26 '14 09:10 Quji

+1

mindmelting avatar Oct 27 '14 14:10 mindmelting

+1

GarPit avatar Oct 28 '14 14:10 GarPit

+1

dslawrence avatar Nov 18 '14 16:11 dslawrence

+1

diaakasem avatar Nov 24 '14 08:11 diaakasem

+1

TheHandsomeCoder avatar Dec 12 '14 16:12 TheHandsomeCoder

+1

picitujeromanov avatar Jan 27 '15 17:01 picitujeromanov

+1

deckchairlabs avatar Feb 02 '15 23:02 deckchairlabs

+1

garhbod avatar Mar 19 '15 09:03 garhbod

The fault is the following line 890

 _.extend(filledValue, data);

When the extend(or even merge) function is used to push the restangular response data into the filledValue it breaks the bindData for the put function.

maybe a callback function could be implemented to simply replace the empty object {} with the data rather than push it with extend

garhbod avatar Mar 19 '15 11:03 garhbod

To try and explain what I was trying to say here is two examples.

First if I manually do what $object does which results and the put containing the original data and not work.

    $scope.itemData = {};
    pagesRest.one(id).get().then(function(data) {
      angular.extend($scope.itemData, data);
    });

The Second is the same result on the front end but makes the save work.

    $scope.itemData = {};
    pagesRest.one(id).get().then(function(data) {
      $scope.itemData = data;
    });

garhbod avatar Mar 19 '15 11:03 garhbod

Someone with a bit more knowledge might come up with a better solution but my pull request #1091 fixed the problem for me.

Based off @gonzofish .restanularizeElement solution from issue #713

garhbod avatar Mar 20 '15 08:03 garhbod

Based on @garhbod's pull request, but without modifying restangular itself, I came up with this quick fix:

    .run(['Restangular', function (Restangular) {
      Restangular.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
        var el = _.extend(deferred.promise.$object, data);
        return Restangular.restangularizeElement(data[Restangular.configuration.restangularFields.parentResource], el, what);
      });
    }])

peter-bertuglia avatar Apr 01 '15 03:04 peter-bertuglia

@peter-bertuglia does that account for data that might be from the server but hasn't been Restangularized?

gonzofish avatar Apr 09 '15 12:04 gonzofish

@gonzofish I'm not sure what you mean by "might be from the server," this code is Restangularizing the object that is definitely coming from the server, it's intercepting the response

peter-bertuglia avatar Apr 09 '15 13:04 peter-bertuglia

Sorry, my fault. I read the code the wrong way...thought it was a request interceptor...stupid me.

gonzofish avatar Apr 09 '15 17:04 gonzofish

I am still experiencing the same issue, it looks like it's been there for a while now... The "copy" method works but it adds quite some load on big objects. Could there be a patch please ?

Truly yours, a coder in pain ;)

olibri-us avatar Nov 10 '16 14:11 olibri-us

yet another +1

victorsosa avatar Nov 11 '16 11:11 victorsosa

+1

saniaky avatar Dec 08 '16 09:12 saniaky

@peter-bertuglia Great !! Here is an upgrade handling collections as well as element.

Restangular.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
    var el = _.extend(deferred.promise.$object, data);

    if(angular.isArray(el))
	return Restangular.restangularizeCollection(data[Restangular.configuration.restangularFields.parentResource], el, what);

    return Restangular.restangularizeElement(data[Restangular.configuration.restangularFields.parentResource], el, what);
});

EDIT

There were too much codes.. this is well enough :

Restangular.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
    return _.extend(deferred.promise.$object, data);
});

With the previous version, if you did a Restangular.extendModel, you received twice each resource instead of once. And when working with events, those were triggered twice..

Bye !

ThomasCedrini avatar Mar 07 '17 16:03 ThomasCedrini