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

angular.copy return [undefined] when copy undefined to array #8610

Closed
wingyplus opened this issue Aug 14, 2014 · 4 comments
Closed

angular.copy return [undefined] when copy undefined to array #8610

wingyplus opened this issue Aug 14, 2014 · 4 comments

Comments

@wingyplus
Copy link

var a = [1,2,3];
angular.copy(undefined, a); // it's returned [undefined, undefined, undefined]

In document said

If source is not an object or array (inc. null and undefined), source is returned.
@kylerob
Copy link

kylerob commented Aug 19, 2014

I'm not sure that returning the source in this case is correct either because the documentation for destination states:

If provided, must be of the same type as source

a's Array type is not the same as undefined, so I wouldn't know what to expect. In fact this should probably result in an error. I have code available (with tests) that throws an error in this case. I'll create a pull request if the team deems that solution the correct approach.

@caitp
Copy link
Contributor

caitp commented Aug 21, 2014

So it's interesting what happens here --- we try to clear dest by deleting properties, but aren't able to because deleting an indexed property from an array doesn't actually affect the length. A simple fix for this would be to detect that destination is an array, and if it is, modify the length when clearing it.

I can make a quick PR for that, but honestly I don't really see the use-case in doing this anyways

@kylerob
Copy link

kylerob commented Aug 21, 2014

@caitp In that case would you remove the documentation for destination that says If provided, must be of the same type as source.?

@caitp
Copy link
Contributor

caitp commented Aug 21, 2014

That line in the docs was added back when forEach() looked like this:

angular.js/src/Angular.js

Lines 581 to 611 in d517bca

function copy(source, destination){
if (!destination) {
destination = source;
if (source) {
if (isArray(source)) {
destination = copy(source, []);
} else if (isDate(source)) {
destination = new Date(source.getTime());
} else if (isObject(source)) {
destination = copy(source, {});
}
}
} else {
if (isArray(source)) {
while(destination.length) {
destination.pop();
}
for ( var i = 0; i < source.length; i++) {
destination.push(copy(source[i]));
}
} else {
forEach(destination, function(value, key){
delete destination[key];
});
for ( var key in source) {
destination[key] = copy(source[key]);
}
}
}
return destination;
}
in 2011.

Now, even back then, there was never any requirement that they were the same type, it just makes more sense if they're the same type (I mean, it doesn't make a whole lot of sense to try to copy undefined into some object --- but I can sort of see how libraries which are wrapping this function might end up doing that based on user supplied data).

So, I dunno, I think it's probably better to keep the line in the docs, just because it's probably better if you do use the same type, but this has never been enforced

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants