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

angular.copy doesn't copy File object correctly #14352

Closed
sbespaly opened this issue Mar 31, 2016 · 6 comments
Closed

angular.copy doesn't copy File object correctly #14352

sbespaly opened this issue Mar 31, 2016 · 6 comments

Comments

@sbespaly
Copy link

Note: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

angular.copy doesn't copy File object (part of file API) correctly. There was the same issue with Blob, but it was fixed.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).

var file = new File([], "filename");
var file2 = angular.copy(file);
//variable 'file2' is not valid, and can not be used with file API anymore.

What is the expected behavior?

copy function should create valid copy of File object, like it was made for Blob

What is the motivation / use case for changing the behavior?

File object and Blob are very common objects, but for some reason copy function doesn't copy File object, but do this for Blob's. This lead to unclear behavior of copy function.

Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.

1.5.3 release and latest sources on GitHub,
All browsers affected
Don't have implementation in previous versions

Other information (e.g. stacktraces, related issues, suggestions how to fix)
add copy code for File object in function
function copyType(source) in file Angular.js line:886

@lgalfaso
Copy link
Contributor

lgalfaso commented Apr 1, 2016

I would like to know what the expectations of supporting this are. If the expectations are that if should be able to take a File that originates from FileList and this from <input type="file">, and that the new File will be able to read the content of the <input>, then it looks like this bug is hiding a large part of the work that is needed.

Note: angular.copy should not be the solution for all things that may need to be copied. There are libraries that specialize in handling many of the browsers quirks and are better suited as a complete solution to clone objects.

@thorn0
Copy link
Contributor

thorn0 commented Apr 2, 2016

Aren't files from <input type="file"> read-only? Why copy them?

@sbespaly
Copy link
Author

sbespaly commented Apr 4, 2016

I'm implementing image editor on client side and user can edit image or use original file without changes. In the first case, after converting canvas to blob my code pass Blob object to other functions and everything is working fine. But in the second case, when user skip changes, I have File object, which is similar to Blob in all cases, except that angular.copy doesn't copy it.
I implemented temporary workaround, by converting File objects to Blob, but it doesn't seem right.

@gkalpak
Copy link
Member

gkalpak commented Apr 7, 2016

The thing is that angular.copy() is not supposed to be a general-purpose copy utility.
It is an internal function, tailored to Angular's need and (the same as with the other helpers) it was exposed in the hope that it might be useful to the users for simple cases and save them having to implement it themselves or use a 3rd party library.
For more advanced usecases (such as dealing with FileList and File objects, one should seek a more specialized solution.

In other words: You should not use angular.copy() on File objects yourself.

There is still a limitation (that should be addressed one way or another), when Angular uses angular.copy() internally of an object that might be or contain a File. IIRC, it is used in ngMock#$httpBackend for copying trained reponse objects (so this shouldn't be an issue, as you can't return a File object to an HTTP request) and in Scope#$watch(..., ..., true) (deep-watching).

I lean towards adding a note in the docs, that you shouldn't deep-watch objects that are or contain File objects and closing this as won't fix.

@eduardomb
Copy link

eduardomb commented Jan 12, 2017

@sbespaly I also agree angular.copy should support File objects.

If this bug closes as a wont fix or lingers opened forever you can use merge:

var myCopy = angular.merge({}, obj)

But it might fail depending on your data, see #12653.

If you don't need deep copy you can also use extend:

var myCopy = angular.extend({}, obj})

It works fine with File objects and is more robust than merge.

It's also a workarround, but if you're still bothered with the overhead of converting File objects to Blob I think this is a bit less hacky.

@sbespaly
Copy link
Author

Actually I need deep copy, that's why I use angular.copy() function.
I added workaround in my code by converting file object into Blob. Which is copied correctly.

Narretz added a commit that referenced this issue Jan 21, 2019
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

6 participants
@thorn0 @lgalfaso @eduardomb @gkalpak @sbespaly and others