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()
}
})
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() {
...
});
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
AngularJS Developer Guide - Modules - Creation versus Retrieval
AngularJS angular.module Function API Reference
Related
Is it possible to call a function from child controller in app.run?
my sub-app facebook controller:
function faceBookController ($scope, $rootScope, faceBookService) {
// I want to call this #scope.init in app.run
$scope.init = function () {
checkLoginState();
};
function checkLoginState () {
faceBookService.init();
}
}
angular.module('app.facebook').controller('faceBookController', ['$scope', '$rootScope', 'faceBookService', faceBookController]);
app.run:
function runFunction (User, $rootScope) {
*****
$window.fbAsyncInit = function() {
FB.init({
appId : '************',
version : 'v2.5' // use graph api version 2.5
});
//Here after facebook sdk connected execute init fruntion from faceBookController.
$rootScope.init();
}
angular.module('app.run', []).run(['User', '$rootScope', runFunction]);
and main app.js file:
angular.module('app', ['ngRoute', 'app.run', 'app.facebook']);
Inside your run you can call the controller function like below
You can give an id for the div where the scope of the controller belongs,
<div id="yourcontainer" ng-app="test" ng-controller="faceBookController">
</div>
and then,
function runFunction (User, $rootScope) {
$window.fbAsyncInit = function() {
FB.init({
appId : '************',
version : 'v2.5' // use graph api version 2.5
});
var scope = ngular.element(document.getElementById('yourcontainer')).scope();
scope.init();
}
Below I have a simple form with a controller and service. Why is there an error thrown when I mention ['angucomplete-alt']
Html
<div ng-controller="Hell">
<input type="button" ng-click="Hello()" value="Save" />
</div>
MyApp.Js
var aap = angular.module('MyApp', ['angularUtils.directives.dirPagination','angucomplete-alt'])
aap.controller('myhmectrl', function ($scope) {
$scope.msg = "Hello Angular....";
})
Conroller.Js
(function () {
angular.module('MyApp', ['angucomplete-alt'])
.controller('Hell', function ($scope, Myservices) {
$scope.Hello = function () {
alert('ok ctrls');
var xx = Myservices.GetSer();
}
});
})
Service.Js
(function () {
angular.module('MyApp', ['angucomplete-alt'])
.service('Myservices', function ($http) {
this.GetSer = function () {
alert('pk Servicess....')
}
})
})
In controller if you are passing the dependencies it will create a new module and instantiate again, Remove the dependency
It shoule be
angular.module('MyApp').controller('Hell', function ($scope, Myservices) {
}
Maybe you didn't include js file for angucomplete-alt ?
You need to remove dependency array when you are accessing your module. Modify your files as belows:
Controller.js
(function () {
angular.module('MyApp')
.controller('Hell', function ($scope, Myservices) {
$scope.Hello = function () {
alert('ok ctrls');
var xx = Myservices.GetSer();
}
});
})
Service.js
(function () {
angular.module('MyApp')
.service('Myservices', function ($http) {
this.GetSer = function () {
alert('pk Servicess....')
}
})
})
I have an angular app and I want to retain some values between controllers using angular service
Here is my base controller:
(function () {
var app = angular.module("MyApp", ["ui.router"]);
app.controller("BaseCtrl", ["$scope", "$http", "$state", BaseControllerFunc]);
function BaseControllerFunc($scope, $http, $state) {
....
}
})();
Now I want to add a service I can later fill with key-value pair data. So I tried adding the following:
app.service("DataService", function () {
var data_item = {};
data_item.Key =MyKey;
data_item.Value=MyValue;
this.MyData.push(data_item);
});
and now it looks like this:
(function () {
var app = angular.module("MyApp", ["ui.router"]);
app.controller("BaseCtrl", ["$scope", "$http", "$state", BaseControllerFunc]);
function BaseControllerFunc($scope, $http, $state) {
....
}
app.service("DataService", function () {
var data_item = {};
data_item.Key =MyKey;
data_item.Value=MyValue;
this.MyData.push(data_item);
});
})();
Here I am stuck. How would I go about injecting values (MyKey and MyValue) into my service? I am newbie with Angular so that makes it hard
Try adding functions to handle your data.
app.service("DataService", function () {
var myData = [];
function addItem(key, value){
var data_item = {Key: key, Value: value);
myData.push(data_item);
}
function getData(){
return myData;
}
return {
add: addItem,
get: getData
}
});
In your controller, use it like
DataService.add('key', 'value');
DataService.get();
change it to
app.service("DataService", function () {
var data_item = {};
return{
function somename(MyKey,MyValue){
data_item.Key =MyKey;
data_item.Value=MyValue;
this.MyData.push(data_item);
}
}
});
and from your controller call it as
DataDervice.somename(MyKey,MyValue)
I have a ng-controller in _Layout page like this.
<div ng-controller="LayoutController">
left content....
#RenderBody
right content..
And using angular module in layout with ajax ( that part works )
<script type="text/javascript">
var module_ = angular.module("myapp", []);
var controller_ = module_.controller("layoutController", function ($scope) {
$.ajax({
type: "POST",
url: "Home/GetMenu",
success: function (result) {
$.each(result, function (i, ix) {
result[i].ID = i + 1;
});
$scope.TopCharactersModel = result;
$scope.$apply();
},
complete: function () {
}
})
Then i want to use another Ng-Controller inside Index.html which derived from this layout page.
Javascript code is not work at this side and chrome debugger show this error
WARNING: Tried to load angular more than once.
<div ng-controller="IndexController">
<div class="panel-group" id="accordion" ng-repeat="arr_ in newsArr">
</div>
</div>
<script>
var module = angular.module("myapp", []);
var myController1 = module_.controller("IndexController", function ($scope) {
$.ajax({
url: "Home/GetNews",
type: "POST",
success: function (result) {
$scope.newsArr = result;
// $scope.$digest();
$scope.$apply()
},
complete: function () {
}
});
});
</script>
For second controller try this.
<script>
var module = angular.module("myapp", []);
var myController1 = module.controller("IndexController", function ($scope) {
$.ajax({
url: "Home/GetNews",
type: "POST",
success: function (result) {
$scope.newsArr = result;
// $scope.$digest();
$scope.$apply()
},
complete: function () {
}
});
});
</script>
Assuming you are within the same app and you're not creating some sort of hybrid application with multiple spa's... you are in fact redeclaring the module: myapp. If you need a reference to the myapp module remove the [] from angular.module("myapp", []);
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.
Pasted from module documentation.
I have integrated requirejs with my angular app.
But while loading app, it gives me an error 'Argument 'appCtrl' is not a function, got undefined'
Here is my controller code :
define(['Angular'], function (angular) {
function appCtrl($scope, pathServices) {
alert('sa');
}
function homeCtrl($scope, brandService) {
console.log('dfd');
}
});
And along with this, it gives error for 'unknown provider pathServices'
Service code is :
serviceConfig.js
define([
'Angular',
'common/Services/services',
'current/js/services'
], function(angular, commonServices, loacalStorageServices, currentServices) {
"use strict";
var services = {
commonServices : commonServices,
currentServices : currentServices,
};
var initialize = function (angModule) {
angular.forEach(services,function(service, name) {
angModule.service(name, service);
});
}
return {
initialize: initialize
};
});
common/services.js
define(['Angular'], function (angular) {
var app = angular.module('myApp.services', []);
app.factory('pathServices', function($http, $q, $rootScope) {
function pathServices() {
alert('as');
}
return new pathServices();
});
app.factory('anotherServices', function($http, $q, $rootScope) {
function anotherServices() {
alert('as');
}
return new anotherServices();
});
});
current/services.js
define(['Angular'], function(angular) {
var app = angular.module('myApp.services', []);
app.factory('brandsService', function() {
function brandsService() {
var autoCompleteData = [];
this.getSource = function() {
return autoCompleteData;
}
this.setSource = function(states) {
autoCompleteData = states;
}
}
return new brandsService();
});
});
in serviceConfig.js I have included 2 service files.. But the problem is, the last current/service.js file overwrites all files.. How can I include multiple service files ?
I am new to requirejs. How can I use controller function and services using requirejs ?
Can anyone help ?
You have to declare your functions in the global (window) namespace, or register them in your module with the moduleName.controller('controllerName',controllerFn)
So either
define(['Angular'], function (angular) {
window.appCtrl = function($scope, pathServices) {
alert('sa');
}
window.homeCtrl = function($scope, brandService) {
console.log('dfd');
}
});
or
define(['Angular'], function (angular) {
var module = angular.module('theModuleName');
module.controller('appCtrl', function($scope, pathServices) {
alert('sa');
});
module.controller('homeCtrl', function($scope, brandService) {
console.log('dfd');
}
});
should fix this error (I prefer the second approach).