Is there a way to initialize some services in angular so that you dont have to repeat calling it? for example
services.factory('Util', ['$http', function($http) {
return {
countries: function() {
return $http.get('/utils/countries/');
},
ivas: function() {
return $http.get('/utils/ivas/');
}
};
}]);
I use this service in several controllers and it takes to long to load all the functions.
Thanks in advance.
You can use something like this, ensure the init method is called when you initialize your app by calling Util.init() then the data will be taken only once from the server, and you can use anywhere
services.factory('Util', ['$http', function($http) {
var me = {
data: {
countries: [],
ivas: []
},
init: function() {
me.data.countries = $http.get('/utils/countries/');
me.data.ivas = $http.get('/utils/ivas/');
},
getCountries: function() {
return me.data.countries;
},
getIvas: function() {
return me.data.ivas;
}
};
return me;
}]);
Related
I want to get a service to story values, that should be available at some controllers, taking regard of this post: AngularJS: How can I pass variables between controllers?
Everything fine. But: I want the service to be available at deeper funtions of controllers. Here is my example:
app.service('activeMovie', function() {
var movie = {
rating: 100
};
return {
getData: function() {
return movie;
},
setRating: function(value) {
movie.rating = value;
console.log("neues Rating" + movie.rating);
},
setData: function(pData) {
movie = pData;
}
};
});
and this are the controllers:
app.controller('MoviesController', function($http, $sce, activeMovie) {
var refresh = function(activeMovie) {
// ...
console.log("Test Service at refresh:" + activeMovie.getData().rating); // WORKS
};
refresh(activeMovie);
this.setActive = function(id, $activeMovie) {
$http.get('movies/'+id).success(function(response) {
// ...
});
console.log("Test Service at setActive:" + activeMovie.getData().rating); // WORKS only with the $-sign in the header
};
}
So it works how I did this.. If I dont use the $-sign in the second function, angularJS throws an error. Obviously I don't have to pass the parameter 'activeMovie' to the funtion when using the $-sign.. but why?
I want to use like below in an AngularJS provider.
provider.files.get();
I hope that files function could have various functions, such as put, update, insert, delete, etc.
my code is below.
but files.get is undefined
what should I do?
please answer me TT
var mod = angular.module('m', []);
mod.provider('provider', function() {
this.$get = function() {
return {
files: function() {
var service = {
get: function() {
console.log('get');
}
};
return service;
}
};
};
return this;
}
The code you have would allow you to do: provider.files().get();
This is because provider.files is a function not an object.
You should change the value of files to the object you've stored in the service variable.
You could also simplify this by using factory instead of provider:
mod.factory('provider', function() {
return {
files: {
get: function() {
console.log('get');
}
}
};
});
Im having problem using $inject.get in angular js..
Let say i have angular services like this
app.service("serviceOne", function() {
this.dialogAlert = function() {
return 'Message One'
};
});
app.service("serviceTwo", function() {
this.dialogAlert = function() {
return 'Message Two'
};
});
app.service("serviceThree", function() {
this.dialogAlert = function() {
return 'Message Three'
};
});
And using the factory to dynamically call dialogAlert()
app.factory("alertService", function($window, $injector) {
if ($window.servicesOne) {
return $injector.get("serviceOne");
} else {
return $injector.get(["serviceTwo", "serviceThree"]);
}
});
With this kind of codes, it gives me "unknown provider".
Or is there any alternative solution for this?
Thanks guys.
injector.get takes only one service name as argument, array is not supported, you may want to do return array of service instances by doing return ["serviceTwo", "serviceThree"].map($injector.get):-
app.factory("alertService", function($window, $injector) {
var service = ["serviceOne"];
if (!$window.servicesOne) {
service = ["serviceTwo", "serviceThree"];
}
return service.map($injector.get); //To be consistent send back this as well as array
});
So with this when you inject the alertService it will return an array of dependecy(ies).
app.controller('MainCtrl', function($scope, alertService) {
// alertService will be array of dependecies.
console.log(alertService.map(function(itm){return itm.dialogAlert()}));
});
Demo
or return with a map:-
app.factory("alertService", function($window, $injector) {
var service = ["serviceOne"],
serviceObjs = {};
if (!$window.servicesOne) {
service = ["serviceTwo", "serviceThree"];
}
angular.forEach(service, function(itm){
serviceObjs[itm] = $injector.get(itm);
});
return serviceObjs;
});
Im trying a service returning multiple resources to be injected in a controller, but calling resource "query" method I get an error that method doesn't exist. below will find the code example of what I want to do. I do method call at controller side because there is additional logic when promise success. Is there a way to do that?
//Service
ImageRepo.factory('ServerCall', ['$resource', function ($resource) {
return {
Image: function () {
return $resource('/api/image/:id', { id: '#id'});
},
Meta: function () {
return $resource('/api/metadata/:id', { id: '#id'});
}
}
}]);
//Controller function
var ImageCtrl = function ($scope, ServerCall) {
...
$scope.metadefsearch = function () {
ServerCall.Meta.query().$promise.then(function (metasdef) {
$scope.metasdefinition = metasdef;
//Some additional logic.....
});
};
};
Let Meta and Image be objects instead of functions:
ImageRepo.factory('ServerCall', ['$resource', function ($resource) {
return {
Image: $resource('/api/image/:id', { id: '#id'});,
Meta: $resource('/api/metadata/:id', { id: '#id'})
};
}]);
Since your two properties are methods you should do this:
ServerCall.Meta().query().$promise.then(function (metasdef) {
I am an angular newbie, I am building an application, one thing really puzzling me is there are couple of ways of defining a service, and I read more from this link: How to define service
then it seems there is no big difference among the ways of defining a service.
but I just noticed one difference which I think is different:
see this service I get from here http://jsfiddle.net/2by3X/5/
var app = angular.module('myApp', []);
app.service('test', function($timeout, $q) {
var self = this;
this.getSomething = function() {
return self.getData().then(function(data) {
return self.compactData(data);
});
};
this.getData = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve("foo");
}, 2000);
return deferred.promise;
};
this.compactData = function(data) {
var deferred = $q.defer();
console.log(data);
$timeout(function() {
deferred.resolve("bar");
}, 2000);
return deferred.promise;
};
});
if I define this service using "factory" like below, one function cannot call other functions of the service.
app.factory('test', function($timeout, $q) {
return {
getSomething : function() {
return getData().then(function(data) {
return compactData(data);
});
},
getData : function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve("foo");
}, 2000);
return deferred.promise;
},
compactData : function(data) {
var deferred = $q.defer();
console.log(data);
$timeout(function() {
deferred.resolve("bar");
}, 2000);
return deferred.promise;
},
};
});
I will get this in the browser console:
[08:41:13.701] "Error: getData is not defined
.getSomething#http://fiddle.jshell.net/_display/:47
Ctrl1#http://fiddle.jshell.net/_display/:75
invoke#http://code.angularjs.org/1.0.0/angular-1.0.0.js:2795
instantiate#http://code.angularjs.org/1.0.0/angular-1.0.0.js:2805
Can anyone explain this? thanks.
you have two big problems there:
the factory returns an object with incorrect syntax.
javascript scope of variables is functional
That is,
You should be returning an object like {key: value, key: value}
values can be functions. however, you return {key = value, key = value}
First fix:
return {
getSomething : function() {...},
getData : function...
}
Secondly, not being able to call functions is normal. See this jsfiddle. I mocked everything. You can call one of the functions returned by the service. However, when from getSomething try to call getData, you get "undefined":
app.factory('testSO', function () {
return {
getSomething: function () {
console.log('return getsomething');
getData();
},
getData: function () {
console.log('return getData');
}...
This would be the same as declaring everything in the scope of the factory function and return references see in jsfiddle:
app.factory('testSO', function () {
var getSomething = function () {
console.log('return getsomething');
};
...
return {
getSomething: getSomething,
...
}
and now you can call local functions as shown in the final version of the jsfiddle:
app.factory('testSO', function () {
var getSomething = function () {
console.log('return getsomething');
getData();
};
...
The original service has something important in it: var self = this; . Some people use var that = this. It's a workaround for an error in ECMA.
In the case of the original code, it's used to "put everything in one object". Functions (properties that happen to be functions) in self need a reference to know where the function you want to call is. Try it yourself here http://jsfiddle.net/Z2MVt/7/