I have angular controller and Javascript function in that function , i am calling angular function. I am getting error: $scope.Name is not a function, $scope.dates is not a function.
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
$scope.Name = function () {
// do something
}
$scope.dates = function () {
// do something
}
working fine inside the controller
var MyController = function ($scope, service)
{
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
$scope.Name = function () {
// do something
}
$scope.dates = function () {
// do something
}
});
working:
var MyController = function ($scope, service)
{
LoginHomeService.getHomeService(function (data) {
$rootScope.CT1SessionObj = data.CT1SessionObj;
validation();
}, function (response) {
alert(response.Message);
});
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
$scope.Name = function () {
// do something
}
$scope.dates = function () {
// do something
});
Not working:
var MyController = function ($scope, service)
{
LoginHomeService.getHomeService(function (data) {
$rootScope.CT1SessionObj = data.CT1SessionObj;
validation();
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
$scope.Name = function () {
// do something
}
$scope.dates = function () {
// do something
}
}, function (response) {
alert(response.Message);
});
});
Declare $scope.Name and $scope.dates on top of validation()
Javascript works from top to bottom, so your functions $scope.Name and $scope.Dates do not exist 'yet'.
Also, try not to use 'Name' as a function. Most of these words are reserved keywords.
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.Name = function() {
// do something
}
$scope.dates = function() {
// do something
}
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
}
Fiddle: http://jsfiddle.net/Lvc0u55v/4872/
An even better approach would be the 'John Papa style' : Y033
Place bindable members at the top of the controller, alphabetized, and not spread through the controller code.
Why?: Placing bindable members at the top makes it easy to read and
helps you instantly identify which members of the controller can be
bound and used in the View.
Why?: Setting anonymous functions in-line can be easy, but when those
functions are more than 1 line of code they can reduce the
readability. Defining the functions below the bindable members (the
functions will be hoisted) moves the implementation details down,
keeps the bindable members up top, and makes it easier to read.
/* avoid */
function SessionsController() {
var vm = this;
vm.gotoSession = function() {
/* ... */
};
vm.refresh = function() {
/* ... */
};
vm.search = function() {
/* ... */
};
vm.sessions = [];
vm.title = 'Sessions';
}
/* recommended */
function SessionsController() {
var vm = this;
vm.gotoSession = gotoSession;
vm.refresh = refresh;
vm.search = search;
vm.sessions = [];
vm.title = 'Sessions';
////////////
function gotoSession() {
/* */
}
function refresh() {
/* */
}
function search() {
/* */
}
}
As #Harald Wiesinger mentioned declare called functions prior to calling function.
Put validation after the scope functions
$scope.Name = function () {
// do something
}
$scope.dates = function () {
// do something
}
function validation() {
$scope.pageload = true;
$scope.Name();
$scope.dates();
}
Related
I have an angular app that will not load and is returning the error message:
Error: [$injector:unpr] Unknown provider: navigatorProvider <-
navigator <- LayoutController
This is ever since I introduced a service I have this registered on the controller, but it still not working. The controller referenced is:
(function () {
"use strict";
angular.module("HtJobPortal").controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "navigator"];
function LayoutController($scope, navigator){
var layout = this;
// Layout
layout.loadTemplate = function() {
return navigator.loadTemplate();
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
}
})();
This is the service:
(function() {
var navigator = angular.module('navigator', []);
navigator.factory('loadTemplate', function () {
var loadTemplate = this;
// Page Directory
navigator.login = "templates/login.html";
navigator.dashboard = "templates/dashboard.html";
navigator.job = "templates/job.html";
// Template switcher
navigator.loadTemplate = function () {
return navigator.login;
}
return loadTemplate;
});
}());
And the app page just in case I've missed something there:
(function () {
'use strict';
angular.module('HtJobPortal', []);
})();
You are add the dependencies when defining the HtJobPortal module
//define dependencies
angular.module('HtJobPortal', ['navigator']);
In the controller, you need to inject the factory in controller
(function () {
"use strict";
angular.module("HtJobPortal").controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "loadTemplate"];
function LayoutController($scope, loadTemplate){
var layout = this;
// Layout
layout.loadTemplate = function() {
return loadTemplate.loadTemplate();
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
}
})();
And define factory as
(function () {
angular.module('navigator', []).factory('loadTemplate', function () {
// Page Directory
var login = "templates/login.html";
var dashboard = "templates/dashboard.html";
var job = "templates/job.html";
return {
// Template switcher
loadTemplate: function () {
return login;
}
};
});
})();
To create a factory\service\controllers , you generally don't require a new module every time. It's preferred to declare one module and register your controller\factory\services to same.
In your case, you can do it like:
(function() {
angular.module('HtJobPortal', [..define other module dependency here..]);
angular.module('HtJobPortal')
.factory('loadTemplate', function () {
var loadTemplate = {};
// Page Directory
loadTemplate.login = "templates/login.html";
loadTemplate.dashboard = "templates/dashboard.html";
loadTemplate.job = "templates/job.html";
// Template switcher
loadTemplate.loadTemplate = function () {
return loadTemplate .login;
}
return loadTemplate; // return object from factory
})
.controller("LayoutController",LayoutController);
LayoutController.$inject = ["$scope", "loadTemplate"]; //inject factory
function LayoutController($scope, loadTemplate){
var layout = this;
// Layout
layout.loadTemplate = function() {
return loadTemplate.loadTemplate(); // call factory method
}
// Initialise pending and set roles
layout.init = function () {
// Global Start up
};
layout.init();
};
}());
I'm using Module pattern, now I wanted to know is that possible to inject one module into another like AngularJs.
Below is sample code that I've tried.
module.js
var AnotherModule = (function () {
function AnotherModule() {
this.anotherFunction = function () {
alert('Inside another Module');
}
}
return AnotherModule;
})(window);
var AnotherModule = new AnotherModule();
var Module = (function (window, AnotherModule) {
function Module(AnotherModule) {
var privateMethod = function() {
}
this.getName = function (brand) {
console.log('Inside get Name');
console.log(AnotherModule);
}
}
return Module;
})(window, AnotherModule);
var module = new Module();
module.getName();
Here is my javascript code
function organization() {
var self = this;
function activate() {
// statements
}
}
I know the scope of the method activate() remains inside the method organization() and that is the challenge I am facing.
My requirement is to write a test in Jasmine to ensure method activate have been called.
it('activate method defined?', function() {
expect(activate()).toBeDefined();
});
but this test is failing with the message
TypeError: activate is not a function
Any inputs to make the above test success will be highly helpful.
You don't need to check that private function 'activate' actually called or defined. You need to check that public function 'organization' as I understand is called or defined and if activate set some public properties etc. For example:
function organization() {
var vm = this;
activate();
function activate() {
vm.activated = true;
}
}
it('should activate organization', function() {
organization();
expect(vm.activated).toBe(true);
});
Or if you need, you can make function activate as public:
function organization() {
var vm = this;
vm.isActivated = false;
vm.activate = activate;
function activate() {
vm.isActivated = true;
}
}
it('should activate organization', function() {
vm.activate();
expect(vm.isActivated).toBe(true);
});
Define the script in this way.
function organization() {
var self = this;
self.activate = function() {
// statements
}}
and access the functiion like this
var obj = new organization();
obj.activate();
I'm trying to use a singleton pattern but I am having trouble with implementing a recursive public function.
var singleton = (function(){
var self = this;
function privateFunc(){
console.log('I can only be accessed from within!');
}
return{
publicFunc: function(){
//More stuff here
setTimeout(self.publicFunc, 1000);
}
}
})();
I am calling it with singleton.publicFunc
I get this error Uncaught TypeError: Cannot call method 'publicFunc' of undefined.
My understanding is var self is actually the Window object in this instance, so I have to pass singleton.publicFunc as the callback for this to work, but it doesn't seem very "DRY" (Don't repeat yourself). Is there
a better way to accomplish this while using a singleton?
With API calls
var wikiAPI = (function(){
var self = this;
return {
getRandomArticle : function() {
return $.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exintro=&format=json&callback=?", function (data) {
});
},
fireAPICalls : function() {
self.getRandomArticle().done(function(data) {
for(var id in data.query.pages) {
this.data = data.query.pages[id];
}
console.log(this.data);
setTimeout(self.fireAPICalls, 1000);
});
}
}
})();
You can use a named function expression like so:
var singleton = (function(){
var self = this;
function privateFunc(){
console.log('I can only be accessed from within!');
}
return{
publicFunc: function nameVisibleOnlyInsideThisFunction(){
//^-------------------------------^
//More stuff here
setTimeout(nameVisibleOnlyInsideThisFunction, 1000);
}
}
})();
I just saw your edit. What would help is having a reference to the functions you are trying to call. So how about something like this:
var wikiAPI = (function(){
var self = this;
var randomArticle = function() {
return $.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exintro=&format=json&callback=?", function (data) {
});
};
var repeatFunc = function fireApi() {
randomArticle().done(function(data) {
for(var id in data.query.pages) {
this.data = data.query.pages[id];
}
console.log(this.data);
setTimeout(fireApi, 1000);
});
};
return {
getRandomArticle : randomArticle,
fireAPICalls : repeatFunc
}
})();
Use bind in the setTimeout() to bind the function to the right scope:
publicFunc: function() {
setTimeout(this.publicFunc.bind(this), 1000);
}
Demo: http://jsfiddle.net/te3Ru/
You can't use this in a IIFE. If you want to use this properly you need to create an object/instance of a function, like so:
var singleton = (function () {
// allow to omit "new" when declaring an object
if (!(this instanceof singleton)) return new singleton();
var self = this, // self now points to "this"
privateFunc = function () {
console.log('I can only be accessed from within!');
};
this.publicFunc = function() {
console.log(this); // this now points to the correct object
setTimeout(function () {
self.publicFunc.call(self); // call function in the "self" scope
}, 1000);
};
return this;
});
singleton().publicFunc();
it's not much of a singleton now, but you can have the closest thing to private and public that javascript has!
I wrote a service. with a function inside it. Is it possible to initialize the service with that function? Have a look at this code.
app.factory('SidebarService',function(){
var self = this;
self.init();
return{
init : function(){
alert("This is sidebar");
}
};
});
I tried to call the init by self.init();. But it is not working.
Pluker Link : http://plnkr.co/edit/gYw2VlneeUIJ7kHJF0Xz?p=preview
app.factory('SidebarService',function(){
var obj = {};
obj.init = function(){
alert("This is sidebar");
}
obj.init();
return obj;
});
Plunk
Try using a .service instead.
app.service('SidebarService',function(){
var self = this;
this.init = function () {
alert("This is sidebar");
};
self.init();
});
See updated plunker:
http://plnkr.co/edit/gjaIudMZaVsKGxIHCYvr?p=preview
Here is a two ways to call inner method for factory:
fessmodule.factory('Data', [ function() {
var inner = function(){
console.log('in inner');
}
inner();
var factory = {
query: function () {
console.log('in query');
},
newone: function(){
return factory.query();
},
inners: function(){
return inner();
}
}
factory.query();
return factory;
}]);
Demo Fiddle