How to call a function from another module - javascript

In my angularJS application, I have two modules : module A and module B.
angular.module('A').controller('ACtrl',function($scope){
$scope.alertA = function(){alert('a');}
//...
});
angular.module('B').controller('BCtrl',function($scope){
//...
});
How to call the function alertA in the module B ?

You need to define a factory in module A:
var moduleA= angular.module('A',[]);
moduleA.factory('factoryA', function() {
return {
alertA: function() {
alert('a');
}
};
});
Then use the alertA factory in module B:
angular.module('B',['A']).controller('BCtrl',function($scope,'factoryA'){
factoryA.alertA();
});

Refactor your code in following these steps:
Define a service in module A
Add module A as dependency to module B
Inject the service into the controller
Here is an example:
angular.module('A').service('API', function ($http) {
this.getData = function () { return $http.get('/data'); };
});
angular.module('B', ['A']).controller('dashboardCtrl', function ($scope, API) {
API.getData().then(function (data) { $scope.data = data; });
});

Related

angular.min.js:63 ReferenceError

Am getting following error when use a factory into angular module
i have factory module like below
angular.module('pollServices', ['ngResource']).factory('Poll', function($resource) {
return $resource('polls/:pollId', {}, {
query: { method: 'GET', params: { pollId: 'polls' }, isArray: true }
})
});
I have another module called polls in the same file, i need to use the factory module to this app so i have called it in module config like
angular.module('polls', ['pollServices'])
When i call the factory inside this module like
function PollListCtrl($scope) {
$scope.polls = Poll.query();
}
am getting error like
angular.min.js:63 ReferenceError: Poll is not defined
at new PollListCtrl (app.js:29)
you didn't call the Poll factory from PollListCtrl
function PollListCtrl(Poll,$scope) {
$scope.polls = Poll.query();
}
You have to inject pollServices to the controller.
angular.module('polls', ['pollServices'])
.controller('PollListCtrl', PollListCtrl)
PollListCtrl.$inject = ["$scope", "pollServices"];
function PollListCtrl($scope, Poll) {
$scope.polls = Poll.query();
}

AngularJS factory unit testing with dependencies

I am trying to test some AngularJS factories with Jasmine. It works fine for factories that don't have any dependencies. One of my factories uses Angular Material's $mdToast as dependency.
The factory:
(function() {
'use strict';
angular
.module('myModule')
.factory('ToastFactory', ToastFactory);
ToastFactory.$inject = ['$mdToast'];
function ToastFactory($mdToast) {
var service = {
showToast1: showToast1,
showToast2: showToast2
};
return service
function showToast1() {
return $mdToast.show($mdToast.build({
templateUrl: 'path'
}));
}
function showToast2() {
return $mdToast.show($mdToast.build({
templateUrl: 'path'
}));
}
}
})();
And here is one of the working tests for another factory without dependencies.
describe('myFactory', function() {
//Injector Service
var $injector;
//Set Module
beforeEach(function() {
angular.module('myModule');
});
//Inject injector service
beforeEach(inject(function() {
$injector = angular.injector(['myModule']);
}));
describe('SampleTest', function() {
it('should be true', function() {
//Arrange
var factory = $injector.get('myFactory');
//Act
var res = factory.testMethod();
//Assert
expect(res).toBe(true);
});
});
})
I know how to do it for controllers, but not for factories.

AngularJS dependency injection timing problems

I have problem related AngularJS dependency injection and timing between them. Here is my code and error
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {},
};
});
module.provider('foo', ['demo', function(demo) {
console.log(demo);
this.$get = function() {
};
}]);
Error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module Demo due to:
Error: [$injector:unpr] Unknown provider: demo
But if I add setTimeout on last definition everything works fine, but its hacking code it shouldn't be like this.
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {},
};
});
setTimeout(function(){
module.provider('foo', ['demo', function(demo) {
console.log(demo);
this.$get = function() {
};
}]);
});
Here is problem on fiddle:
http://jsfiddle.net/zcf7rb4s/1/
You cannot add demo as a dependency there because it does not yet exist. That's the way the $injector works. What you can do is list demo as a dependency in the $get function of the provider. That's going to be executed by the $injector after all providers have been defined.
Check this:
<div ng-app="Demo">
<div ng-controller="test">{{x}}</div>
</div>
And the definitions:
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {x: 'x'},
};
});
module.provider('foo', function() {
this.$get = function(demo) {
return {
demo: demo
};
};
});
module.controller('test', ['$scope', 'foo', function($scope, foo) {
$scope.x = foo.demo.data.x;
}]);
The code inside the factory and provider is run at "step 1".
Then, in "step 2" AngularJS binds the controller. It first uses $injector to inject the dependencies (that have been previously defined in "step 1"). So in practice your $timeout "emulates" this behavior, that's why it works. But it's wrong, that's not the way you are supposed to use them.
Inject into the provider like this instead:
module.provider('foo', function() {
this.$get = ['demo', function(demo) {
console.log(demo);
}];
});

Angular injecting $rootScope in provider

I cannot access $rootScope inside of a provider.I looked lot of angular other modules implementations. it is the same as how i implemented.
What is wrong?
it tried urload as a separate function(similar to other getValue function) it did not work
Error is $emit is undefined
define(['angularAMD'], function () {
var contextServiceModule = angular.module('contextService', []);
var contextService = function () {
var context = {};
this.$get = ['$rootScope', function ($rootScope) {
console.log($rootScope);
return function (){
return {
init: init,
getValue: getValue,
setValue: setValue,
urlLoad: function () {
$rootScope.$emit('onInit', {});/// error here
}
};
};
}];
this.init = function () {
return context;
};
this.getValue = function (key) {
var value = context[key] ? context[key] : null;
return value;
};
this.setValue = function (key, value) {
context[key] = value;
};
}
contextServiceModule.provider('contextService', contextService);
});
You can't inject $rootScope into the provider $get function because it isn't yet available. However, you can inject it manually when the function is called.
this.$get = ['$injector', function ($injector) {
return function (){
return {
init: init,
getValue: getValue,
setValue: setValue,
urlLoad: function () {
var $rootScope = $injector.get('$rootScope');
console.log($rootScope);
$rootScope.$emit('onInit', {});/// error here
}
};
};
}];
Angular providers are created during the configuration phase and $rootScope isn't available until the app run phase. Here are a couple Angular resources on it and a similar question:
https://docs.angularjs.org/guide/module
https://docs.angularjs.org/guide/providers
https://stackoverflow.com/a/10489658/3284644
That's how i was getting $rootScope to broadcast messages from React.js to Angular.
In case if your ng-view isn't located in body, use yours instead.
function $broadcast(event, args]) {
angular.element('body').injector().invoke([
'$rootScope',
'$timeout',
($rootScope, $timeout) =>
{
args.unshift(event);
$timeout(() => {
$rootScope.$broadcast.apply($rootScope, args);
});
}
]);
}
Got it from here:
https://www.bimeanalytics.com/engineering-blog/you-put-your-react-into-my-angular/
!! IMPORTANT: The below solution does not work when minified. For this you need to do dependency injection, but than $get cannot be called during config phase
app.provider('someHandler', function() {
this.$get = function ($rootScope) {
function doBroadcast(words) {
$rootScope.$broadcast(words);
}
return {
shout: function (words) {
doBroadcast(words);
}
}
}
});
If you need to use in the config phase you can do the following
app.config(['someHandlerProvider', function(someHandlerProvider) {
someHandlerProvider.$get().shout('listen up');
}
During run you can just do someHandler.shout('listen up')

how to get a service from angularjs app

I have a variable that contains my angular app
(was instantiated with:)
var app = angular.module('app', [...]);
And I want to get the $timeout service.
How can I get this service from the it?
I want something like:
var timeout = app.getService('$timeout');
or
app.something('$imeout', function($timeout) {
...
} // like controller() does
Where I want to use it:
define([], function () { // I can import my angular module 'app', or 'angular'
return {
'some_function': function () {
$timeout(function() { ... do something ... }, 1000);
}
}
}
This is a service (with requirejs), and my controllers will require it.
What you should do is:
app.controller("myCtrl",["$timeout", "otherService" ,function($timeout, otherService){
$timeout(function() {
otherService.updateService('Hi');
}, 3000);
}]);

Categories