Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Resource clobbering moment objects #3767

Closed
gingermusketeer opened this issue Aug 27, 2013 · 4 comments
Closed

Resource clobbering moment objects #3767

gingermusketeer opened this issue Aug 27, 2013 · 4 comments

Comments

@gingermusketeer
Copy link

For the project I am working we are making use of a custom $httpProvider.defaults.transformResponse handler. It is doing things like converting to camel case and turning dates strings into momentjs objects.

This approach has mostly been working except I have run into an issue where the moment objects are being turned into normal objects. Looking at the source it appears that the issue is to do with angular.copy not preserving the object state/behavior. I tried to get around this by using setters and getters but these are also lost in translation. It would be great if there was some way to customise/configure the resource constructor or perhaps the copy function to prevent this.

angular -v => 1.0.7

@jankuca
Copy link
Contributor

jankuca commented Sep 25, 2013

Got a demo?

@petebacondarwin
Copy link
Contributor

@gingermusketeer - So when angular.copy does its thing, it should also copy over the prototype of the object?

@gingermusketeer
Copy link
Author

I think so. Looks like angular.copy takes all the properties from the prototype and includes them in the new object directly rather then linking with the prototype. To me it would make sense if the new object behaved exactly like the one it was created from. e.g changing original objects prototype would alter it for the new object as well.

@gingermusketeer
Copy link
Author

@jankuca something like what is below should be enough to show what happens

function Test(){}

a = new Test()
// Test {}

b = angular.copy(a)
// Object {}

Test.prototype.aprop = 3

a.aprop
// 3

b.aprop
// undefined

ckknight pushed a commit to ckknight/angular.js that referenced this issue Jul 16, 2014
So far, angular.copy was copying all properties including those from
prototype chain and was losing the whole prototype chain (except for Date,
Regexp, and Array).

Deep copy should exclude properties from the prototype chain because it
is useless to do so. When modified, properties from prototype chain are
overwritten on the object itself and will be deeply copied then.

Moreover, preserving prototype chain allows instanceof operator to be
consistent between the source object and the copy.
Before this change,

    var Foo = function() {};
    var foo = new Foo();
    var fooCopy = angular.copy(foo);
    foo instanceof Foo; // => true
    fooCopy instanceof Foo; // => false

Now,

    foo instanceof Foo; // => true
    fooCopy instanceof Foo; // => true

The new behaviour is useful when using $http transformResponse. When
receiving JSON data, we could transform it and instantiate real object
"types" from it. The transformed response is always copied by Angular.
The old behaviour was losing the whole prototype chain and broke all
"types" from third-party libraries depending on instanceof.

Closes angular#5063
Closes angular#3767
Closes angular#4996

BREAKING CHANGE:

This changes `angular.copy` so that it applies the prototype of the original
object to the copied object.  Previously, `angular.copy` would copy properties
of the original object's prototype chain directly onto the copied object.

This means that if you iterate over only the copied object's `hasOwnProperty`
properties, it will no longer contain the properties from the prototype.
This is actually much more reasonable behaviour and it is unlikely that
applications are actually relying on this.

If this behaviour is relied upon, in an app, then one should simply iterate
over all the properties on the object (and its inherited properties) and
not filter them with `hasOwnProperty`.

**Be aware that this change also uses a feature that is not compatible with
IE8.**  If you need this to work on IE8 then you would need to provide a polyfill
for `Object.create` and `Object.getPrototypeOf`.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants