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) { ....
Related
How to Define a new function in angular can anybody please help me out
My code is like this:
var app = angular.module('rtsApp', ['ngMaterial', 'ngMessages', 'ngStorage','ngRoute', 'restangular','timepickerPop', 'ngStomp', 'ngCookies', 'angular-cron-gen','uiSwitch','ngMaterial', 'md.data.table']);
app.config(function(RestangularProvider) {
newFunction(RestangularProvider);//I need newFunction here
RestangularProvider.setDefaultHeaders({
"X-API-KEY": "sks#2017",
"Content-Type": "application/json"
});
Actually I am Getting This Error
Failed to instantiate module rtsApp due to:
ReferenceError: newFunction is not defined
at http://localhost:3000/dist/js/scripts.min.js:1738:5
at Object.invoke (http://localhost:3000/dist/js/vendor.min.js:82:460)
at d (http://localhost:3000/dist/js/vendor.min.js:80:333)
at http://localhost:3000/dist/js/vendor.min.js:80:472
at q (http://localhost:3000/dist/js/vendor.min.js:46:7)
at g (http://localhost:3000/dist/js/vendor.min.js:80:234)
at gb (http://localhost:3000/dist/js/vendor.min.js:84:352)
at c (http://localhost:3000/dist/js/vendor.min.js:60:57)
at Wc (http://localhost:3000/dist/js/vendor.min.js:60:370)
at ye (http://localhost:3000/dist/js/vendor.min.js:59:45)
try it :-
another scenario is follow below code,
'use strict';
var deck = angular.module('app',
['ui.router',other lib...]);
angular.module("app").config(["$breadcrumbProvider", "$httpProvider", function ($breadcrumbProvider, $httpProvider) {
$breadcrumbProvider.setOptions({
prefixStateName: 'userHome.main',
template: 'bootstrap3'
});
//Do No Remove This Line
$httpProvider.defaults.withCredentials = true;
}]);
Create a file and define a module in the file. For example create globalFunctions.js and add this file to your index.html file with this :
<script src="/path/to/file/location/globalFunctions.js"></script>
Define a module and also your global functions. like this:
(function () {
angular.module('test', []);
})();
function test() {
console.log("test");
}
Inject it in main app (app.module.js) and call it:
(function() {
'use strict';
var app = angular.module('app', [
'test',
...
]);
app.config(function($routeProvider, $locationProvider) {
test();
});
})();
Update
All files for a simple test:
app.module.js
(function () {
var app = angular.module('app', [
'ngRoute',
'global'
]);
app.config(function ($routeProvider, $locationProvider) {
test();
});
})();
test.module.js
(function () {
angular.module('global', []);
})();
function test() {
console.log("it is test function here");
}
index.html
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.16/angular-route.min.js"></script>
<script src="app.module.js"></script>
<script src="test.module.js"></script>
<body ng-app="app">
<h2>It is a test</h2>
</body>
</html>
This Plunker provided for my solution
How do I pass the value of a constant from one module to another? Thank you in advance. Here's the Plunker demo. The constant "config" is defined in app.module.js, and I want to be able to pass it to the child.module.js for defining constant "childConfig". Right now the console is saying "config is not defined".
Thank you very much in advance.
// app.module.js
(function(){
"use strict";
var myApp = angular
.module("myApp", ["child"]);
myApp.constant("config", {
rootURL: "components/"
, version: "myApp1.0.0"
})
})();
// app.component.js
(function(){
"use strict";
// Define controller
function mainController(){
this.$onInit = function() {
var mainVM = this;
mainVM.parent = {
"lastName": "Smith"
, "firstName": "Jordan"
};
};
}
// Define component
var mainComponent = {
controller: mainController
, controllerAs: "mainVM"
};
// Register controller and component
angular.module("myApp")
.controller("mainController", mainController)
.component("mainComponent", mainComponent);
})();
//components/child.module.js
(function(){
"use strict";
var child = angular.module("child", []);
child.constant("childConfig", config);
})();
//components/child.component.js
(function(){
"use strict";
// Define controller
function childController(config) {
this.$onInit = function() {
var vm = this;
vm.getTemplateUrl = function(){
return config.rootURL + 'child.html';
}
vm.rootURL = config.rootURL;
vm.version = config.version;
vm.child = {
"firstName": "Jack"
}
};
// end of $onInit()
}
// Define component
var child = {
//templateUrl: vm.getTemplateUrl + "child.html"
//templateUrl: "components/child.html"
template: "<ng-include src='vm.getTemplateUrl()'/>"
, controller: childController
, controllerAs: "vm"
, bindings: {
parent: "<"
}
};
// Register controller and component
angular.module("child")
.controller("childController", childController)
.component("child", child);
})();
<!DOCTYPE html>
<html>
<head>
<script src="//code.angularjs.org/snapshot/angular.js"></script>
<link rel="stylesheet" href="style.css">
<script src="app.module.js"></script>
<script src="app.component.js"></script>
<script src="components/child.module.js"></script>
<script src="components/child.component.js"></script>
</head>
<body ng-app="myApp" ng-controller="mainController as mainVM">
Parent: {{mainVM.parent.firstName}} {{mainVM.parent.lastName}}<br>
<child parent="mainVM.parent"></child>
</body>
</html>
I think you might've misunderstood the constant factory's capabilities. It's not supposed to be mutable neither variable, therefore it won't be able to use another external provider to compose it's value, it'll only serve a plain value that is pure.
On the other hand, if you don't mind, a factory can be use to achieve the result your are looking for. Basically you can create a factory that fabricate a string for you based on the injected config provider.
For example:
child.factory("childConfigURL", ['config', function(config) {
return config.rootURL + "/component/";
}]);
The only problem with this approach is that it can't be injected into a module configuration function, because it's not pure anymore and needs to be bootstrapped to resolve it's dependencies.
Note on constants:
constant(name, value);
Register a constant service with the $injector, such as a string, a
number, an array, an object or a function. Like the value, it is not
possible to inject other services into a constant.
But unlike value, a constant can be injected into a module
configuration function (see angular.Module) and it cannot be
overridden by an AngularJS decorator.
Ref.: $provide.constant
I have the the following files:
index.html
<html ng-app="gitHubViewer">
<head>
<script data-require="angular.js#*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
<script data-require="angular-route#*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular-route.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
<script src="MainController.js"></script>
<script src="gitHub.js"></script>
</head>
<body>
<h1>GitHub Viewer</h1>
<div ng-view>
</div>
</body>
</html>
main.html
<form name="searchUser" ng-submit="search(username)">
<input type="search" required="" placeholder="Username to find" ng-model="username" />
<input type="submit" value="Search" />
</form>
app.js
(function(angular) {
'use strict';
angular.module('gitHubViewer', ['ngRoute'])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.otherwise({
redirectTo: "/main"
});
}
]);
})(window.angular);
MainController.js
(function(angular) {
'use strict';
angular.module('gitHubViewer', [])
.controller('MainController', ['$scope', '$interval', '$location',
function($scope, $interval, $location) {
var decrementCountdown = function() {
$scope.countdown -= 1;
if ($scope.countdown < 1) {
$scope.search($scope.username);
}
};
var countdownInterval = null;
var startCountdown = function() {
countdownInterval = $interval(decrementCountdown, 1000, $scope.countdown);
};
$scope.search = function(username) {
if (countdownInterval) {
$interval.cancel(countdownInterval);
$scope.countdown = null;
}
};
$scope.username = 'angular';
$scope.countdown = 5;
startCountdown();
}
]);
})(window.angular);
My problem is that the main.html file is not being loaded on ng-view when i have the routing on a separated file (app.js).
But if i remove the app.js file and add the .config on MainController.js,the main.html loads properly, here's the example:
(function(angular) {
'use strict';
angular.module('gitHubViewer', ['ngRoute'])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.otherwise({
redirectTo: "/main"
});
}
])
.controller('MainController', ['$scope', '$interval', '$location',
function($scope, $interval, $location) {
var decrementCountdown = function() {
$scope.countdown -= 1;
if ($scope.countdown < 1) {
$scope.search($scope.username);
}
};
var countdownInterval = null;
var startCountdown = function() {
countdownInterval = $interval(decrementCountdown, 1000, $scope.countdown);
};
$scope.search = function(username) {
if (countdownInterval) {
$interval.cancel(countdownInterval);
$scope.countdown = null;
}
};
$scope.username = 'angular';
$scope.countdown = 5;
startCountdown();
}
]);
})(window.angular);
Am i doing something wrong with the separated the files???
I think you are defining your module twice with the same name, instead add a handle to it and use that.
var app = angular.module('gitHubViewer', []);
app.controller(...
app.config(...
Here's your plunkr edited to work:
plunkr
You need to declare the module that is shared between scripts outside the IIFE, so that it is a global variable to be shared. See: IIFE and scope
That is app.js now has the module defined at the top:
var app = angular.module("gitHubViewer", ["ngRoute"]);
(function() {
and this line was removed from MainController.js:
var app = angular.module("gitHubViewer", ["$scope", "$interval", "$location"]);
Note: You also don't need to inject scope or services like $location, that are included in the base angularJs package, into the module. These should be injected directly into controllers.
Note: after the countdown the plunkr now breaks, because you need to add your UserController in.
When you create a new module you use the dependency array argument
angular.module('gitHubViewer', ['ngRoute']);
Then when you want to reference the existing module you leave out the second argument.
angular.module('gitHubViewer').run...
angular.module('gitHubViewer').controller....
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', []);
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 */
}]);
})();