angularjs [ng:areq] Argument 'fn' is not a function, got string - angularjs

I am new to angular js..I am getting follwing error please help me out
[ng:areq] Argument 'fn' is not a function, got string
var app = angular.module('demo',[]);
app.config('$routeProvider',function($routeProvider){
$routeProvider.when('/add',{
templateUrl:'demo/add.html',
controller:'addcontroller'
}).
when('/order',{
templateUrl:'demo/order.html',
controller:'ordercontroller'
});
});
app.controller('addcontroller',function($scope){
$scope.message="order";
});
app.controller('ordercontroller',function($scope){
$scope.message="order";
});

I think the error is in the config block, it should either be:
app.config(function($routeProvider){
// routeProvider config
});
or better:
app.config(['$routeProvider', function($routeProvider){
// routeProvider config, allows minification
}]);
the annotations are there for minification to work correctly. You can read more about it on AngularJS docs https://docs.angularjs.org/tutorial/step_05
Please note that this practice needs to be done throughout the app to work correctly.

Although not directly related to the context of this question, this error message can also be caused by a resolve block returning something else than a function, like this:
$stateProvider.state('mystate', {
url: "/myurl",
templateUrl: "mytemplate.html",
controller: "MyController",
resolve: {
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser
}
});
if securityAuthorizationProvider.requireAuthenticatedUser happens to be undefined, you can get this error.

I know this is an older post, but thought I'd contribute what was wrong with my code with this exact error. I was injecting a service into my controller this way:
theApp.directive('theDirective', 'myService', ['$http', function ($http, myService) {}]);
Instead of this:
theApp.directive('theDirective', ['$http', 'myService', function ($http, myService) {}]);
Notice that my service was included outside of the inline array annotation! It was a boneheaded move on my part that cost me way too much time.

For the the problem was defining factory dependency outside the array. Most probably the minification was also an issue.
//Error in this
angular
.module('mymodule').factory('myFactory', 'thisconstant', function (thisconstant) {
});
This fixed by
//correct code
angular
.module('mymodule').factory('myFactory', ['thisconstant', function (thisconstant) {
}]);

Since there's been various use cases added here, I thought I'd also add mine. I got this error when re-formating a function service
angular
.app('myApp')
.service('MyService', function (){
// do something
return MyService;
})
into a class object:
export default class MyService { ... }
angular
.app('myApp')
.service('MyService', MyService);
My problem was that my service was returning itself at the end of the function and I needed to add a class function, which would do this:
export default class MyService {
constructor(){
// doing something
}
get() {
return MyService;
}
}
which fixed the issue for me. :)

I got this error by misunderstanding the way anonymous functions and named functions are treated in JavaScript.
This causes the error:
angular.module("app").factory("myDataService", ['$resource', myDataService]);
var myDataService = function($resource) {
return $resource('/url');
}
I should've either done this:
var myDataService = function($resource) {
return $resource('/url');
}
angular.module("app").factory("myDataService", ['$resource', myDataService]);
Or this:
angular.module("app").factory("myDataService", ['$resource', myDataService]);
function myDataService($resource) {
return $resource('/url');
}
More on the difference between anonymous function and named function here

In First line you need to use like this,
var app = angular.module('demo', ['ngRoute']);
and use the routing thing like this,
$routeProvider.when('/add').then({
templateUrl:'demo/add.html',
controller:'addcontroller'
});
Just try these steps once.

Related

How to use module function inside another factory in angularjs

I have configurations.js file which having
var configurationModule = angular.module('configuration', ['restangular', 'notification']);
configurationModule.factory('clientConfigSvc', function (notificationMgr, $interpolate, $injector) {
function getConfig(configKey) {
return getNestedPropertiesByString(activeEnvironment, configKey);
}
}
and having another javascript file with below code
angular.module('ds.coupons').factory('CouponsREST', ['Restangular', 'SiteConfigSvc', 'settings',function (Restangular, siteConfig, settings, configurationModule) {
configSvc.getConfig('services.baseUrl'); /// need to call this function
}
Actually i want function configSvc.getConfig inside second angular factory
Yes After tired of trying lots of solution, today morning working on moving train got idea to fix, dont know if its correct way but its working. but still looking for correct fix if mine was not correct as per angularjs practise.
Here is my solution.
1. I added configuration module in app.js alogn with other
window.app = angular.module('ds.app', [
'restangular',
'ui.select',
'ui.router',
'ds.shared',
'ds.utils',
'ds.i18n',
'configuration']);
I added clientConfigSVC in my factory where i want to use configuration function
angular.module('ds.coupons')
.factory('CouponsREST', ['Restangular', 'SiteConfigSvc','settings', 'clientConfigSvc',
function(Restangular, siteConfig, settings, clientConfig) { }
and then inside CouponsREST factory with function clientConfig.getConfig() i am getting value

Angular JS - service not working

I am using a service to get data from the server using $http.get() method. I am calling the function in the service and then accessing its variable from the controller. But it is not working this way.
The code is below
'use strict';
var mission_vision_mod = angular.module('myApp.mission_vision', ['ngRoute']);
mission_vision_mod.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/mission_vision', {
templateUrl: 'partials/mission_vision/mission_vision.html',
controller: 'mission_visionCtrl'
});
}]);
mission_vision_mod.controller('mission_visionCtrl', ['$scope','getMissionData','$http', function($scope, $http, getMissionData) {
$scope.visiontext = "Here is the content of vision";
getMissionData.getmissiondata();
$scope.missions = getMissionData.missiondata;
$scope.len = $scope.missions.length;
}]);
mission_vision_mod.service('getMissionData', ['$rootScope','$http', function($rootScope, $http){
var missiondata;
function getmissiondata(){
$http.get('m_id.json').success(function(data){
missiondata = data;
});
}
}]);
When i write the$http.get() function in the controller itself, it works. I am new to angular JS.
Try writing your service like this
mission_vision_mod.service('getMissionData', ['$rootScope','$http', function($rootScope, $http){
this.getMissionData=function(){
return $http.get('m_id.json');
}
}]);
Use Service in controller like this:
mission_vision_mod.controller('mission_visionCtrl', ['$scope','getMissionData','$http', function($scope,getMissionData,$http) {
$scope.visiontext = "Here is the content of vision";
getMissionData.getMissionData().success(function(response){
$scope.missions=response;
$scope.len = $scope.missions.length;
}).error(function(errorl){
//handle error here
});
}]);
Also I suggest using a better name for service -'MissionDataService' :)
EDIT- Your sequence of injected service should match sequence of injectable names specified in the array..See my last edit
['$scope','getMissionData','$http',
function($scope, $http, getMissionData
The service names don't match with the variable names.
My advice: stop using this array notation. It clutters the code and is a frequent source of bugs. Use ng-annotate.
That said, your service is not correctly defined. It doesn't have any member function that would allow it to be called. Re-read the documentation of services. Defining services using factory() is easier than defining them using service(), BTW. And the service should return the promise returned by $http. Trying to access the value returned by an asynchronous call right after making the asynchronous call will never work. Read http://blog.ninja-squad.com/2015/05/28/angularjs-promises/
Try:
mission_vision_mod.service('getMissionData', ['$rootScope','$http', function($rootScope, $http){
var missiondata;
function getmissiondata(){
$http.get('m_id.json').success(function(data){
missiondata = data;
return missiondata;
});
}
}]);

Conditionally inject angular module dependency

I'm new to angular and have the following code.
angular.module('MyApp')
.controller('loginController', ['$scope', '$http', 'conditionalDependency',
function ($scope, $http, conditionalDependency{
}
I would like to have conditionalDependency loaded conditionally. Something like this
if(true)
{
//add conditionalDependency
}
How can this be done. I've seen this post . However, my requirement is that I have the dependency specified in function
Thanks in advance.
Not quite clear as to why you would have to have it in a named function like in your example but...
If you need conditional dependencies, I would suggest taking a look at the following:
Conditional injection of a service in AngularJS
I've used this method in a couple niche scenarios and it works quite well.
EXAMPLE:
angular.module('myApp').controller('loginController',
['$injector', '$scope', '$http',
function($injector, $scope, $http) {
var service;
if (something) {
service = $injector.get('myService');
}
});
You can use it even without injecting injector in your controller
if(something){
var injector = angular.element(document).injector();
var myService = injector.get('myService')
}
Use:
angular.injector().get('conditionalDep');
You can inject $injector once to your file and call $injector.get('dep');

routeprovider using resolve to pass value to controller

I'm looking for a way to pass a value to my controller from my appRoutes. With the idea for it to call a function and do some magic. heres some code so you get an idea:
appRoutes.js
$routeProvider
.when('/students/some/path/:id', {
templateUrl: 'views/studentRecord.html',
controller: 'StudentsController',
resolve: { myVar: 'test' }
});
studentsCtrl.js
angular.module('StudentsCtrl', [])
.controller('StudentsController', function($scope, $http, $routeParams,
$location, myVar, Students) {
/* ... */
});
Ideally, I'd like to call a given function within this controller - but parsing a value would be just as good. The idea is that the controller handles all pages to do with 'students' and will make some http calls so my node server will do some calls to mongodb. Ive tried a few variations on the internet and with no luck. I got an error:
Error: $injector:unpr Unknown Provider
but I'm not sure how to resolve it.
EDIT: I've half resolved this now by using this; http://plnkr.co/edit/mSb58e8cGDNYU27xSizk?p=preview
ideally i'd like to separate the app.js into controllers and services - currently working on this, any edit of the plnkr would be great.
Question still stands of is it possible to hit a function within the controller first, rather than resolving one through a service?
In each resolve property, you can have a function that lets Angular inject services for you to use:
resolve: {
myVar1: function(testService) { return testService.fetchList1(); },
myVar2: function(anotherService, $http) {
// call service functions to mongo-db or what have you
return result;
}
}
Then, your controller, just inject the properties:
// myVar1 and myVar2 are now here
app.controller('StudentsController', function($scope, myVar1, myVar2) {
/* ... */
});
If the returned value from the function inside resolve is a promise, then it will be resolved before controller code is called (hence, the name resolve). This is actually the recommended approach as it makes service code (such as testService) reusable across many controllers.
Passing a function that returns the value
.state('tab2', {
url: '/tab2',
templateUrl: 'templates/tab2.html',
controller: 'Tab2Controller as tab2Ctrl',
//promise
resolve: {
lastName: function () { return 'makarov'}
}
});
Then in the controller
function Tab2Controller(lastName) {
console.log("Tab2", lastName);
}

AngularJS Dynamic loading a controller

I read a lot about lazzy loading, but I am facing a problem when using $routeProvider.
My goal is to load a javascript file which contains a controller and add a route to this controller which has been loaded previously.
Content of my javascript file to load
angular.module('demoApp.modules').controller('MouseTestCtrlA', ['$scope', function ($scope) {
console.log("MouseTestCtrlA");
$scope.name = "MouseTestCtrlA";
}]);
This file is not included when angular bootstap is called. It means, I have to load the file and create a route to this controller.
First, I started writing a resolve function which has to load the Javascript file. But declaring my controller parameter in route declaration gave me an error :
'MouseTestCtrlA' is not a function, got undefined
Here is the call I am trying to set :
demoApp.routeProvider.when(module.action, {templateUrl: module.template, controller: module.controller, resolve : {deps: function() /*load JS file*/} });
From what I read, the controller parameter should be a registered controller
controller – {(string|function()=} – Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string.
So I write a factory which should be able to load my file and then (promise style!) I whould try to declare a new route.
It gave me something like below where dependencies is an array of javascript files' paths to load :
Usage
ScriptLoader.load(module.dependencies).then(function () {
demoApp.routeProvider.when(module.action, {templateUrl: 'my-template', controller: module.controller});
});
Script loader
angular.module('demoApp.services').factory('ScriptLoader', ['$q', '$rootScope', function ($q, $rootScope) {
return {
load: function (dependencies)
{
var deferred = $q.defer();
require(dependencies, function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}
}
}]);
Problem
I still have this javascript error "'MouseTestCtrlA' is not a function, got undefined" which means Angular could not resolved 'MouseTestCtrlA' as a registered controller.
Can anyone help me on this point please ?
Re-reading this article http://ify.io/lazy-loading-in-angularjs/ suggested to keep a $contentProvider instance inside Angular App.
I came up with this code in my app.js
demoApp.config(function ($controllerProvider) {
demoApp.controller = $controllerProvider.register;
});
It enables me to write my controller as expected in a external javascript file :
angular.module("demoApp").controller('MouseTestCtrlA', fn);
Hope this can help !

Resources