Skip to content

Upgrade to 1.x.x - TypeError: "Uploader" must be an instance of FileUploader #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
davidwparker opened this issue Jul 22, 2014 · 18 comments

Comments

@davidwparker
Copy link
Contributor

When migrating, following the guide: https://github.com/nervgh/angular-file-upload/wiki/Migrate-from-0.x.x-to-1.x.x

I now get the following error whenever I use any of the directives:

TypeError: "Uploader" must be an instance of FileUploader
    at link (http://localhost:3000/assets/angular/angular-file-upload.js?body=1:1231:27)
    at nodeLinkFn (http://localhost:3000/assets/angular/angular.js?body=1:6228:13)
    at compositeLinkFn (http://localhost:3000/assets/angular/angular.js?body=1:5638:15)
    at compositeLinkFn (http://localhost:3000/assets/angular/angular.js?body=1:5641:13)
    at nodeLinkFn (http://localhost:3000/assets/angular/angular.js?body=1:6222:24)
    at http://localhost:3000/assets/angular/angular.js?body=1:6422:13
    at http://localhost:3000/assets/angular/angular.js?body=1:7574:11
    at wrappedCallback (http://localhost:3000/assets/angular/angular.js?body=1:10950:81)
    at wrappedCallback (http://localhost:3000/assets/angular/angular.js?body=1:10950:81)
    at http://localhost:3000/assets/angular/angular.js?body=1:11036:26

The element:

<input nv-file-select uploader="{{uploader}}" type="file" multiple="" class="hidden-file" id="attachment{{uploader._timestamp}}">

Any thoughts on what I should be looking at?

@davidwparker
Copy link
Contributor Author

It appears I'm having some race conditions. It seems that ng-file-select directive is trying to read from the uploader attribute before it's ready to be used (my own directive, which has ng-file-select within it, creates the uploader). So it's still not created when it's called, but then it's created a moment later and then it's usable.

@nervgh
Copy link
Owner

nervgh commented Jul 23, 2014

Did you see this?

@davidwparker
Copy link
Contributor Author

@nervgh - yeah, I have something similar, but I'm calling the whole thing from within a directive. So it's something like:

.directive('attachmentsBar', function(FileUploader) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl:'attachments/_bar.html',
    link: function(scope, element, attrs) {
      var uploader = scope.uploader = new FileUploader();
...

But what ends up happening is it hits this new code:

throw new TypeError('"Uploader" must be an instance of FileUploader');

within:

.directive('nvFileSelect', ['$parse', 'FileUploader', function($parse, FileUploader) {
        return {
            link: function(scope, element, attributes) {
                var uploader = scope.$eval(attributes.uploader);

                if (!(uploader instanceof FileUploader)) {
                    throw new TypeError('"Uploader" must be an instance of FileUploader');
                }

                var object = new FileUploader.FileSelect({
                    uploader: uploader,
                    element: element
                });
            }
        };
    }])

But because of the way the directive works (calling the nv-file-select directive), it seems that nv-file-select doesn't wait until the uploader is created, so it's null when it first gets into the directive.

@nervgh
Copy link
Owner

nervgh commented Jul 23, 2014

You can use ng-if directive:

<element ng-if="case">
    <input type="file" nv-file-select uploader="uploader"/>
</element>

@davidwparker
Copy link
Contributor Author

@nervgh - that wouldn't work either.

Here's a plunker of my exact problem:
http://plnkr.co/edit/SnoWSQDjqFrKArST4cDR?p=info

@nervgh
Copy link
Owner

nervgh commented Jul 24, 2014

For example:

  1. ng-if
  2. directive.compile
  3. rootScope & instance of FileUploader

@davidwparker
Copy link
Contributor Author

Thanks @nervgh - I think I should be able to get it working with those examples.

@elise-fastpay
Copy link

What was the solution to this problem?

@davidwparker
Copy link
Contributor Author

@elise-fastpay -

I have the following template (used in a directive "A"):

<input nv-file-select uploader="uploader" type="file" multiple class="hidden-file" id="attachment{{uploader._timestamp}}" />

With that directive being called from another template in another directive "B":

        <attachments-bar uploader="uploader"></attachments-bar>

And the uploader being created in directive "B" compile/pre:

compile: function() {
      return {
        pre: function(scope, element, attrs) {
          scope.uploader = new FileUploader();
        },

@jackhsu978
Copy link

@nervgh the ng-if trick works for me. thanks!

@daleholborow
Copy link

I think, to avoid confusion, in @davidwparker 's solution, the uploader=uploader attribute on the attachments-bar directive definition is unnecessary, the nv-file-select uploader=x refers to the scope.x = new FileUploader... i was able to get this working without the additional attribute but found it confusing figuring out which "uploader" was which giving the same name being used all throughout the code. Hope this helps make it even clearer. Thanks guys, i was tearing my hair out for a while on this problem

@davidwparker
Copy link
Contributor Author

@daleholborow - I only had to do that because I had an inner directive that needed access to the same Uploader as the parent directive. Works pretty well and is necessary for the two to talk.

@daleholborow
Copy link

Ooooh... then that might come in handy for me as well - I hadn't realised that subtlety. Cheers mate!

@cesarmarinhorj
Copy link

this was my first error when trying make things work.
basically, the code in example must be in first line of controller function. when i write it inside a function of my controller, gave me this error.
writing exactly like the code in example, in firsts lines of controller, and no error was found.
thanks!

@owenXin
Copy link

owenXin commented Apr 28, 2016

The ng-if = "uploader" works for me. @nervgh Thanks very much. I'm integrate this upload to angular-formly, and it works fine in formlyConfig.setType().

@paresh-icoder
Copy link

paresh-icoder commented May 31, 2016

angular fileuploader is not working plz help me
var uploader = vm.uploader = new FileUploader({
url: 'server/upload.php'
});

@ishwarpohani
Copy link

@paresh-icoder

See: #574

You need to change references from "uploader" to "vm.uploader" in html file.

@Tailent
Copy link

Tailent commented Apr 26, 2017

ng-if also works for me.@nervgh,ありがとう :)

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

No branches or pull requests

10 participants