Why isn't my angular factory loading? - angularjs

Example... Plunker
addon.js:
(function () {
'use strict';
angular.module('jzAddons', [])
.factory('jzThemeFac', function () {
return {
themes:[
{
name: 'none',
url: '',
margin: '8px',
bg: '#ffffff'
},
{
name: 'amelia',
url: '//netdna.bootstrapcdn.com/bootswatch/3.1.0/amelia/bootstrap.min.css',
margin: '6px',
bg: '#108a93'
}
],
changeTheme: function (theme) {
var oldLink = angular.element('#bootstrapTheme');
oldLink.remove();
if (theme.name !== 'none') {
var head = angular.element('head');
head.append('<link id="bootstrapTheme" href="' + theme.url + '" rel="stylesheet" media="screen">');
}
currentTheme = theme;
}
};
});
})();
app.js:
var app = angular.module('example', ['jzAddons']);
(function () {
'use strict';
app.controller('MainCtrl', ['jzThemeFac', function ($scope, jzThemeFac) {
$scope.themes = jzThemeFac.themes; /* Error comes from this line */
}]);
})();
At the bottom of my body tag I've got:
<script src="addon.js"></script>
<script src="app.js"></script>
I keep getting the error:
TypeError: Cannot read property 'themes' of undefined

Your factory inject was wrong, you can do:
app.controller('MainCtrl', ['$scope', 'jzThemeFac', function ($scope, jzThemeFac) {...
or just:
app.controller('MainCtrl', function ($scope, jzThemeFac) {
edit: you can also move:
(function () {
'use strict';
to the beginning of file

You need to remember to inject $scope into your MainCtrl. So app.js should look like this:
var app = angular.module('example', ['jzAddons']);
(function () {
'use strict';
app.controller('MainCtrl', ['$scope', 'jzThemeFac', function ($scope, jzThemeFac) {
$scope.themes = jzThemeFac.themes; /* Error comes from this line */
}]);
})();

Related

Angular service not being passed into angular controller

Would anyone know why my service is not being passed into controller. I receive an error: Argument 'fn' is not a function.
references within my main web page:
<script src="~/js/app-categories.js"></script>
<script src="~/js/addingNewTaskService.js"></script>
<script src="~/js/addNewTaskController.js"></script>
app-categories.js:
(function () {
"use strict";
angular.module("app-categories", ["simpleControls", "ngRoute", "ngAnimate", "addNewTask"])
.config(function ($routeProvider) {
...
});
})();
addingNewTaskService.js:
(function () {
"use strict";
alert("inside service");
angular.module("app-categories")
.service('addingNewTaskService'), function () {
};
})();
addNewTaskController.js:
(function () {
"use strict";
angular.module("app-categories")
.controller("addNewTaskController", addNewTaskController);
function addNewTaskController($scope, $http, addingNewTaskService) {
...
}
})();
You have a syntax error here:
.service('addingNewTaskService'), function () {
};
That should be:
.service('addingNewTaskService', function() {
});

Can not access an app's constant from a service

What do i have to do in myService.js to access the constant 'appSettings' from app.js?
app.js
(function () {
'use strict';
angular
.module('myApp', ['ngMaterial'])
.constant('appSettings', {
someValue: 123
})
})();
Here is my services/myService.js
(function () {
'use strict';
angular
.module('myApp')
.factory('myService', ['appSettings', MyService]);
function MyService(appSettings) {
console.log(appSettings.someValue)
}
})();
Browser's console says appSettings.someValue is undefined`
Not sure what is the problem you are facing but I can access the value.
(function() {
'use strict';
angular
.module('myApp', [])
.constant('appSettings', {
someValue: 123
})
})();
(function() {
'use strict';
angular
.module('myApp')
.factory('myService', ['appSettings', MyService]);
function MyService(appSettings) {
console.log(appSettings.someValue);
alert(appSettings.someValue);
return {
foo: function() {}
}
}
angular.module("myApp")
.controller("sa", function($scope, myService) {
myService.foo();
})
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="sa"></div>

bootstraping angular value provider

My app.js, service.js, controller.js are declared as below. My problem is the controller only pickup the initial values {userId: -1, networkName: 'xyz'} set in the service.js, even though the values are changed to { userId: 129, networkName: 'mydomainaccoutname' } in myApp.run() block in the app.js. I have correctly injected the value provider to myApp.run() as well as the controller. How do I get the controller to pick up the updated values? Thanks.
app.js
(function () {
'use strict';
//debugger;
var myApp = angular.module('myApp', [
// Angular modules
'ngAnimate', // animations
//'ngRoute', // routing
'ngSanitize', // sanitizes html bindings (ex: sidebar.js)
'ui.router', // state routing
'ui.grid',
'ui.grid.pagination',
'ngResource', // RESTful resource
// Custom modules
'common', // common functions, logger, spinner
'common.bootstrap', // bootstrap dialog wrapper functions
// 3rd Party Modules
'ui.bootstrap' // ui-bootstrap (ex: carousel, pagination, dialog)
]);
myApp.run(['$templateCache', '$rootScope', '$state', '$stateParams', 'currentUserAccount', 'userFactory',
function ($templateCache, $rootScope, $state, $stateParams, currentUserAccount, userFactory) {
//currentUserAccount is a value provider service
currentUserAccount = { userId: 129, networkName: 'mydomainaccoutname' };
}]);
})();
service.js
'use strict';
angular.module('myApp')
.value('version', '5.0')
.value('currentUserAccount', {
userId: -1,
networkName: 'xyz'
});
controller.js
(function () {
'use strict';
//debugger;
var controllerId = 'shellCtrl';
angular.module('cmtApp').controller(controllerId,
['$rootScope', 'common', 'config', 'currentUserAccount', shell]);
function shell($rootScope, common, config, currentUserAccount) {
var vm = this;
var logSuccess = common.logger.getLogFn(controllerId, 'success');
var events = config.events;
vm.busyMessage = 'Please wait ...';
vm.isBusy = true;
vm.isAdmin = false;
vm.currentUser = currentUserAccount;
vm.spinnerOptions = {
radius: 40,
lines: 7,
length: 0,
width: 30,
speed: 1.7,
corners: 1.0,
trail: 100,
color: '#F58A00'
};
activate();
function activate() {
logSuccess('CMT loaded!', null, true);
common.activateController([], controllerId);
}
};
})();
Why not use a actual service instead? You can have your service like follows.
angular.module('app')
.service('UserService', [function() {
var currentUser = {
userId: -1,
networkName: 'xyz'
};
var getCurrentUser = function() {
return currentUser;
};
var setCurrentUser = function(user) {
currentUser = user;
};
// public functions
return {
getCurrentUser: getCurrentUser,
setCurrentUser: setCurrentUser
};
}]);
Then in your controller, you can do something like this:
(function () {
'use strict';
//debugger;
var controllerId = 'shellCtrl';
angular.module('cmtApp').controller(controllerId,
['$rootScope', 'common', 'config', 'UserService', shell]);
function shell($rootScope, common, config, UserService) {
var vm = this;
....
vm.currentUser = UserService.getCurrentUser();
...
};
})();
Then in your app runner:
myApp.run(['$templateCache', '$rootScope', '$state', '$stateParams', 'UserService', 'userFactory',
function ($templateCache, $rootScope, $state, $stateParams, currentUserAccount, userFactory) {
//currentUserAccount is a value provider service
UserService.setCurrentUser({ userId: 129, networkName: 'mydomainaccoutname' });
}]);

Angular Controller error 'Argument 'MainCtrl' is not a function, got undefined'

At some point this afternoon I suddenly got the following AngularJS error: Argument 'MainCtrl' is not a function, got undefined
I have a good version still running in Chrome without any errors, so I'm attempting to find the diffs - however to no avail.
I would appreciate any advice on how to fix the error Argument 'MainCtrl' is not a function, got undefined
I load the controllers.js file in index.html - within the body section:
<!DOCTYPE html>
<html ng-app="rage.ui">
<head>
<!-- loading css files here... -->
</head>
<body ng-controller="MainCtrl as main">
<!-- Wrapper-->
<div id="wrapper">
<!-- Navigation -->
</div>
<script src="app/app.js"></script>
<script src="app/config.js"></script>
<script src="app/js/controllers.js"></script>
</body>
Here's the MainCtrl in my controllers.js file (also loaded in index.html) -
* MainCtrl - controller */
(function () {
'use strict';
angular.module('rage.ui')
.controller('MainCtrl', ['$scope', '$interval', '$window', 'widgetDefinitions', main])
.factory('widgetDefinitions', [widgetDefinitions])
.value('defaultWidgets', [
{ name: 'random' },
{ name: 'time' },
{ name: 'datamodel' },
{
name: 'random',
style: {
width: '50%'
}
},
{
name: 'time',
style: {
width: '50%'
}
}
]);
function main($scope, $interval, $window, widgetDefinitions, defaultWidgets) {
this.userName = 'Risk user';
// ...
}
function widgetDefinitions(RandomDataModel) {
return [
{
name: 'random',
directive: 'wt-scope-watch',
attrs: {
value: 'randomValue'
}
}
{
name: 'treegrid',
templateUrl: 'app/views/templateGadget/treeGrid.html',
title: "Tree Grid Report",
attrs: {
width: '50%',
height: '250px'
}
}
];
}
})();
in my attempt to add a new 'gadgetModelFactory' to the malhar Angular-Dashboard framework, I broke my system.
Here's the good version of my new factory, now fixed:
'use strict';
angular.module('rage').
factory('gadgetDataModel', function ($scope, WidgetDataModel) {
function gadgetDataModel() {
var test = 123;
}
gadgetDataModel.prototype = Object.create(WidgetDataModel.prototype);
gadgetDataModel.prototype.constructor = WidgetDataModel;
angular.extend(gadgetDataModel.prototype = {
init: function () {
// to be overridden by subclasses
var dataModelOptions = this.dataModelOptions;
},
destroy: function () {
// to be overridden by subclasses
WidgetDataModel.prototype.destroy.call(this);
$interval.cancel(this.intervalPromise);
}
});
});
and my app.config:
(function () {
angular.module('rage.ui', [
'ui.router',
'ui.bootstrap',
'ui.dashboard'
])
})();
Have a look at other posts (AngularJS error: 'argument 'FirstCtrl' is not a function, got undefined')
Check whether you defined ng-app properly
Check whether you have listed the JS files properly in the index
Try to rewrite your controllers to the more conventional way (see egghead.io tutorials)
Maybe you have two files .js with same module name. Eg.:
file1.js:
var appControllers = angular.module('appControllers', []);
file2.js:
var appControllers = angular.module('appControllers', []);

Linking a Service from different file

I have following code:
JS:
var myApp = angular.module('app',['ngDropdowns', 'dataStoreService']);
myApp.controller('myCtrl', function($scope) {
$scope.ddSelectOptions = [
{
text: 'Option1',
iconCls: 'someicon'
},
{
text: 'Option2',
someprop: 'somevalue'
},
{
// Any option with divider set to true will be a divider
// in the menu and cannot be selected.
divider: true
},
{
// Example of an option with the 'href' property
text: 'Option4',
href: '#option4'
}
];
$scope.ddSelectSelected = {}; // Must be an object
});
and in DataStoreService.js:
var myApp = angular.module('app');
myApp.factory('dataStoreService', ['$rootScope', function ($rootScope) {
var service = {
model: {
name: '',
email: ''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
}]);
But, I am getting the following error:
https://docs.angularjs.org/error/$injector/nomod?p0=dataStoreService - Module 'dataStoreService' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
How do I resolve it? How can i link different controllers and services in different files to my app?
app.js
// Declare the main module
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl1', ['$scope', 'MyService', '$window', function($scope, MyService, $window) {
var str = MyService.getHello();
$window.alert(str);
}]);
aService.js
angular.module('myApp').
service('MyService', function() {
return {
getHello: function () {
return 'hello';
},
}
}
);
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
</head>
<body>
<p>An example showing how to share data between controllers using a service</p>
<div ng-controller="Ctrl1">
<h2>Controller 1 Says:</h2>
</div>
<script src="http://code.angularjs.org/1.2.1/angular.js"></script>
<script src="app.js"></script>
<script src="aService.js"></script>
</body>
</html>
inject it in the controller rather than application:
var myApp = angular.module('app',['ngDropdowns']);
myApp.controller('myCtrl', ['$scope', 'dataStoreService', function($scope, dataStoreService) { ....
here,
var myApp = angular.module('app',['ngDropdowns']);
you don't need the 'dataStoreService' define as a dependency here, its not a module its just a service, so if you need that service inside controller inject it into the controller like below,
myApp.controller('myCtrl', function($scope,dataStoreService) { ....

Resources