0

I am trying to do a file upload using angularjs. But I am getting this error for the past few days and I am unable to resolve:

angular.js:13920 Error: [$injector:unpr] http://errors.angularjs.org/1.5.8/$injector/unpr?p0=fileUploadServiceProvider%20%3C-%20fileUploadService%20%3C-%20appCtrl

at angular.js:38
at angular.js:4511
at Object.d [as get] (angular.js:4664)
at angular.js:4516
at d (angular.js:4664)
at e (angular.js:4688)
at Object.invoke (angular.js:4710)
at S.instance (angular.js:10354)
at p (angular.js:9263)
at g (angular.js:8620)

I only want to read the files uploaded, and store it in the server, and not to link to other URL. I am using Django for my backend. This are my codes:

HTML

<body ng-app="myApp">
    <div ng-controller="appCtrl">
        <input type="file" id="file" name="files" accept="text/*"
               data-url="file" class="upload" ng-model="uploadFile"/>
        <label for="file">
          <span class="glyphicon glyphicon-open" id="selectFile">
          </span>Select a file
        </label>
    </div>
</body>
<script src="../static/js/services/fileUploadService.js"></script>
<script src="../static/js/controllers/fileUploadController.js"></script>
<script src="../static/js/fileModel.js"></script>

Directives:

var app = angular.module('myApp', [])
app.directive("filesInput", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});

Service

var app = angular.module('myApp', [])
app.factory('fileUploadService', function ($rootScope) {
    var _files = [];

    var service = {
        add: add,
        clear: clear,
        upload: upload,
      }

     return service 

     function add(file){
        _files.push(file)
        $rootScope.$broadcast('fileAdded', file.files[0].name)
      }
      function clear(){
        _files = []
      }
      function upload(){
        _files.submit();        
      }

Controller:

var app = angular.module('myApp', [])
app.controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
    $scope.$watch('uploadFile', function (newVal, oldVal) {
        var submitBtn = document.getElementById('submitBtn');
        //clear existing files
        fileUploadService.clear()
        if(newVal == true){
            var formdata = new FormData();
            $scope.getTheFiles = function ($files) {
                angular.forEach($files, function (value, key) {
                    formdata.append(key, value);
                });
            };    
            // NOW UPLOAD THE FILES.
            $scope.uploadFile = function () {    
                var request = {
                    method: 'POST',
                    url: file,
                    data: formdata,
                    headers: {
                        'Content-Type': undefined
                    }
                };    
                // SEND THE FILES.
                $http(request)
                    .success(function (d) {
                        alert(d);
                    })
                    .error(function () {
                    });
            }
        }]);
        fileUploadService.add(newVal)
        fileUploadService.upload()
    }
})
4
  • Is app declared somewhere? I only see uploadComponent module Commented Dec 23, 2019 at 12:07
  • You didn't show the relevant part - The error say that the fileUploadService service was not found. Probably because you didn't add it to your app's dependencies Commented Dec 23, 2019 at 12:10
  • @AlonEitan It's actually in my script, which I've forgot to show. I've added them. Commented Dec 23, 2019 at 12:42
  • @BillP yes, controller, service and directive all have var app = angular.module('myApp', []) Commented Dec 23, 2019 at 12:46

2 Answers 2

2

By using this:

var app = angular.module('myApp', [])

it creates a new module, so controller, service and directive are registered in a separate module! This results in the injection error as controller cannot inject the service, as it is registered in a different module.

The solution is to only create one module and register all the other components in it, like this:

1st file:

var app = angular.module('myApp', []);
angular.module('myApp').factory('fileUploadService', function ($rootScope) {
   ... 
});

2nd file

angular.module('myApp').controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
  ...
});

3rd file:

angular.module('myApp').directive("filesInput", function() {
  ...
});
Sign up to request clarification or add additional context in comments.

12 Comments

Also, after the first script with var app = angular.module('myApp', []) it can be written like var app = angular.module('myApp'); app.directive("filesInput", function() {}); and so on for services and components.
what do you mean by "register all the other components in it"? so I create directive, controller, and service in one page? sorry, I'm new to angularjs.
@lealceldeiro so I don't need to declare var app = angular.module('myApp', []) again for all?
@user3774763, no you don't. Just after the first call to angular.module('myApp', []) (creating the module), you can simply do angular.module('myApp').directive|factory|component|<any-other>... this will locate the module and create whatever you put after: a factory, directive, etc
They can be in separate files as they already are.But you have to create the application module(app) only once, as lealceldeiro describes
|
1

Avoid multiple statements that create the module.

ERRONEOUS

var app = angular.module('myApp', [])
app.directive("filesInput", function() {
  //...
});

var app = angular.module('myApp', [])
app.factory('fileUploadService', function ($rootScope) {
  //...
}};

var app = angular.module('myApp', [])
app.controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
  //...
});

The extra angular.module('myApp', []) statements are overwriting existing modules, resulting in the fileUploadService becoming unregistered.

BETTER

angular.module('myApp', [])

angular.module('myApp').directive("filesInput", function() {
  //...
});

angular.module('myApp').factory('fileUploadService', function ($rootScope) {
  //...
}};

angular.module('myApp').controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
  //...
});

The statement creating the module must be placed before all the code adding more entities to it.

From the Docs:

Creation versus Retrieval

Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.

For more information, see

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.