Can i use one service into another angular service? Else what will be the best approach to accomplish the below?
First Service:
var app = angular.module("MyApp", []);
app.service('Service1', function () {
return {
FirstFunction: function () {
return "something";
}
}
});
Second service:
app.service('Service2', function () {
return {
SecondFunction: function () {
//How to use FirstFunction of Service1 ???
}
}
});
Thanks
app.service('Service2', function (Service1) {
return {
SecondFunction: function () {
Service1.FistFunction
}
}
});
As long as service2 doesnt depend on service1 there is no problem.
app.service('Service2', function (Service1) {
return {
SecondFunction: function () {
Service1.FirstFunction();
}
}
});
Related
I have the following services:
DataService.js
app.service("DataService", [
function () {
this.getData = function () { return "original value" }
}
]);
LocationService.js
app.service("LocationService", ["DataService",
function(dataSvc) {
this.getLocationData = function () {
return dataSvc.getData();
}
}
]);
Now for testing LocationService.js, how do mock DataService inside of LocationService?
This is what I currently have for LocationService_tests.js:
describe("LocationService", function () {
var locationSvc;
beforeEach(module('myModule'));
beforeEach(inject(function (LocationService) {
locationSvc = LocationService;
}));
describe("getLocationData", function () {
it("returns the location data", function () {
var mockLocationDataValue = "mocked value";
// ???
// I want to mock dataSvc.getData within getLocationData
// so it returns "mocked value" instead of "original value"
expect(locationSvc.getLocationData()).toBe(mockLocationDataValue);
});
});
});
You could mock whole service using $provide API's service method, and change your service to returned mock data.
describe("LocationService", function () {
var locationSvc;
beforeEach(module('myModule'));
beforeEach(module(function($provide) {
$provide.service('LocationService', function() {
this.getData = function() {
return "mock value";
}
});
});
beforeEach(inject(function (LocationService) {
locationSvc = LocationService;
}));
...
});
I want to move this function to services.js:
News.all().async().then(function(data) {
$scope.news = data['data']['NewsList'];
});
And than call it in controller.js by this command:
$scope.news = News.all();
I try many ways, but them did not work.
Here is my services.js:
.factory('News', function($http) {
function returnNews() {
return {
async: function() {
return $http.get('test.json');
}
};
}
return {
all: function() {
return returnNews();
}
}
});
Well if you call News.all() in the end you will get an object with an async property: {async} and I don't think this is what you want. What you can do is pass a callback to the service:
.factory('News', function($http) {
return {
all: function(callback) {
return $http.get('test.json').then(callback);
}
}
});
and in the controller you have to do:
News.all(function(data){
$scope.news = data
});
I have a factory where I wanna return a promise inside a function but my controller says everytime something like:
Provider 'personFactory' must return a value from $get factory method.
My factory:
(function () {
'use strict';
angular
.module('testApp')
.factory('personFactory', personFactory);
personFactory.$inject = ['storage'];
function personFactory(storage) {
storage.getData().then(function (response) {
return {
allData: function () {
return response
}
}
});
}
})();
My controller:
(function () {
'use strict';
angular
.module('testApp')
.controller('menuListController', menuListController);
menuListController.$inject = ['$scope', 'personFactory', '$rootScope'];
function menuListController($scope, personFactory) {
$scope.fromFactory = personFactory.allData();
console.log($scope.fromFactory)
}
})();
I think I have to double return both the functions, but can't get the syntax right to call it also in the controller if that is the problem.
Your factory definition has to return something, that's the problem:
function personFactory(storage) {
return storage.getData().then(function (response) {
return {
allData: function () {
return response
}
}
});
}
Now, I don't know if that's what you really need. I usually return a function or object in the factory that then I use.
With your approach you will invoke getData only once and receive the promise directly in your controller.
I like it, now that I think about it :)
But! Looking at the rest of your code, I think you're not expecting to get the promise after all.
You would have to do something like this anyway:
personFactory.then(function () {
$scope.fromFactory = data.allData();
});
Which again makes me think you don't need to do that allData business. Here's what I'd do:
function personFactory(storage) {
return storage.getData();
}
personFactory.then(function (response) {
$scope.fromFactory = response;
});
How does that look?
Can we call the factory functions defined in one module from another module? If so, how?
Let's say my first module is defined in moduleOne.js file as:
var myModule = angular.module('MyServiceModuleOne', []);
myModule.factory('notify', function () {
return {
sampleFun: function () {
// some code to call sampleFunTwo()
},
};
});
And my second module in moduleTwo.js as:
var myModuleTwo = angular.module('MyServiceModuleTwo', []);
myModuleTwo.factory('notifytwo', function () {
return {
sampleFunTwo: function () {
// code
},
};
});
How to call sampleFunTwo() from sampleFun()?
Thanks.
You need to inject MyServiceModuleTwo into MyServiceModule:
var myModuleTwo= angular.module('MyServiceModuleTwo',[]);
var myModule= angular.module('MyServiceModuleOne', ['MyServiceModuleTwo']);
Then inject notifytwo into notify:
myModule.factory('notify', function(notifytwo) {
return {
sampleFun: function() {
notifytwo.sampleFunTwo();
}
};
});
myModuleTwo.factory('notifytwo', function() {
return {
sampleFunTwo: function() {
alert('From notify two');
}
};
});
And the code on plunker
Factory:
factory('cordovaReady', function () {
return function (fn) {
var queue = [];
var impl = function () {
queue.push(Array.prototype.slice.call(arguments));
};
document.addEventListener('deviceready', function () {
queue.forEach(function (args) {
fn.apply(this, args);
});
impl = fn;
}, false);
return function () {
return impl.apply(this, arguments);
};
};
})
I used this factory in another factory like this:
return {
getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {
//
}
}
The cordovaReady factory will execute the passed callback when the deviceReady event was fired. My question is how do I use it in controller?
I tried with just
.controller( 'HomeCtrl', function HomeController($scope, cordovaReady) {
cordovaReady(function(){
//do stuff
});
});
But it did not work. No console errors. Any ideas?
I solved it by wrapping the factor like this
.factory('aUseCase', function ($q, $rootScope, cordovaReady) {
return {
doSomething: cordovaReady(function () {
//do stuff
})
};
})
better version of #artworkad :
.factory('aUseCase', ['$q', '$rootScope', 'cordovaReady', function ($q, $rootScope, cordovaReady) {
return {
doSomething: cordovaReady(function () {
//do stuff
})
};
}])
Don't forget to inject dependencies explicitly otherwise you will have problem when minifying this snippet.
Are you sure your dependency is being injected into your controller?
var MyController = function($scope, cordovaReady) {
...
}
MyController.$inject = ['$scope', 'cordovaReady'];
In controller you need to declare a function to use cordovaReady
myApp.controller("salaryCalculatorCtr", ['$scope', 'cordovaReady'
, function ($scope, cordovaReady) {
var initApp= cordovaReady(function () {
//do something
});
initApp();
}]);