Best way to save and use config settings in AngularJS - angularjs

I'm new to AngularJS and just building an app to learn it. My app calls a REST API and right now I have the hostname hard coded in the app. I want to make this in app setting (and maybe later have somewhere to configure it). I thought I'd start with a constant. Should it go in my app.js like this? If so, I'm not sure of the syntax for adding it to the .config settings with $routeProvider there too
(function () {
// Define module and add dependencies inside []
var app = angular.module("haClient", ["ngRoute"]);
app.constant('hostname', 'http://192.192.192.192:8176');
app.config(function ($routeProvider) {
$routeProvider
// Register routes
// Main route
.when("/main", {
templateUrl: "main.html",
controller: "MainController"//,
//activeTab: 'home'
})
// Device List
.when("/devices", {
templateUrl: "devicelist.html",
controller: "DeviceListController"
})
// Device details (param is device name)
.when("/device/:devicename", {
templateUrl: "device.html",
controller: "DeviceController"
})
// Invalid URL's get sent back to main route
.otherwise({ redirectTo: "/main" });
}); // End App Config
}());
This is the module that needs to use it (called from controllers):
(function () {
var deviceCtrl = function ($http) {
var getDevices = function () {
return $http.get("http://192.192.192.192:8176/devices.json/")
.then(function (response) {
return response.data;
});
};
// get details and return a promise
var getDeviceDetails = function (deviceName) {
return $http.get("http://192.192.192.192:8176/devices/" + deviceName + ".json/")
.then(function (response) {
return response.data;
});
};
// Public API
return {
getDeviceDetails: getDeviceDetails,
getDevices: getDevices
};
};
var module = angular.module("haClient");
}());
Can someone enlighten em on the best way to set it and get it?
Thanks

I currently do this by using templates to build the root .html file in the backend. Eg, using doT templates in node.js, I put this below my other js includes:
<!-- load any templated constants -->
<script>
angular.module('mymod').constant('globals', {
api: '{{=it.api}}'
});
</script>
This way my backend can work out the logic of where the client needs to point to. In order to use the value in another service or controller, you simply inject the constant by name:
angular.module('somemod', []).factory('myservice', ['globals', function(globals){
// use globals.api or what ever you set here for example
}]);

The best place to do configuration is in a Provider and inside your config block.
Providers expose an API that allows you to configure your service before it's injected into your controllers and directives.
Suppose you have a service called myService that you want injected into your controller function like this:
app.controller('ctrl', function($scope, myService) { ...});
And myService is responsible for retrieving data through web API calls. Let's further assume that you would like to configure your service with the root URL htt://servername/, since all calls will share the same host name.
You can define your myServiceProvider like this:
app.provider('myService', function(){
var webapiurl;
this.setWebServiceUrl = function (url) {
webapiurl = url;
}
// the injector will call the $get function to create the singleton service that will be injected
this.$get = function( /*injectables*/) {
return {
getData: function() {... Use webapiurl ...}
}
}
});
Then in your config function, configure your provider:
app.config(function(myServiceProvider){
myServiceProvider.setWebServiceUrl('htt://servername');
});
Finally you can inject the service anywhere it can be injected:
app.controller('ctrl', function($scope, myService) {
$scope.data = myService.getData();
});

I couldn't get the supplied answers to work (no reason to think they wouldn't). here's what I did.
My main app.js (constants section)
(function () {
// Define module and add dependencies inside []
var app = angular.module("haClient", ["ngRoute"]);
//constants
app.constant('mySettings', {
baseURL: 'http://192.192.192.192:8176',
otherSetting: 'XYZ'
});
app.config(function ($routeProvider) {
$routeProvider
// Register routes
// Main route
.when("/main", {
templateUrl: "main.html",
controller: "MainController"//,
//activeTab: 'home'
})
// Device List
.when("/devices", {
templateUrl: "devicelist.html",
controller: "DeviceListController"
})
// Device details (param is device name)
.when("/device/:devicename", {
templateUrl: "device.html",
controller: "DeviceController"
})
// Invalid URL's get sent back to main route
.otherwise({ redirectTo: "/main" });
}); // End App Config
}());
In my service (added mySettings as a dependency and then just used mySettings.baseURL):
(function () {
var deviceCtrl = function ($http, $log, mySettings) {
$log.info("DeviceCtrl - baseURL: " + mySettings.baseURL);
// get device list and return a promise
var getDevices = function () {
return $http.get(mySettings.baseURL + "/devices.json")
.then(function (response) {
return response.data;
});
};
// get details and return a promise
var getDeviceDetails = function (deviceName) {
$log.info("DeviceCtrl - Getting device info for " + deviceName);
return $http.get(mySettings.baseURL + "/devices/" + deviceName + ".json")
.then(function (response) {
return response.data;
});
};
// Public API
return {
getDeviceDetails: getDeviceDetails,
getDevices: getDevices
};
};
var module = angular.module("haClient");
module.factory("deviceCtrl", deviceCtrl);
}());
I'm certainly no expert (as is clear from not being able to get supplied answers working), and I'm not sure (yet) if there are any drawbacks to this method. It allowed me to get on with my project and learn more of Angular, so I went with it.
Regards
Mark

I have used another module and injected it into app module like this
Create constant.js and include that in your index.html & add following code inside that
angular.module('constantsModule', []).constant('BASEURL', 'http://google.com');
Inside app.js, inject 'constantsModule' so that all constants inside it will be available for 'haClient'
angular.module('haClient', [
'constantsModule'
])
.config(function ($routeProvider) {
.when('/', {
templateUrl: 'views/landing.html',
controller: 'landingCtrl'
})
});
Inside landingCtrl, since its in scope of 'haClient', we can inject BASEURL constant from 'constantsModule'
angular.module('haClient').controller('landingCtrl', function ($scope, BASEURL) {
// just to show, how to access it inside controller
$scope.baseurl = BASEURL;
});

Related

Unable to inject my service in Angular resolve inside router configuration

(My plunkr code resides at http://plnkr.co/edit/6KU3GblQtMdRAx3v3USV?p=preview)
I'm trying to create a Search bar (in navigation) which should ultimately hit the backend REST API. The input search button when clicked on input 'alpha' would trigger a route to products/search/0?searchtext=alpha
Clicking on the button triggers a route change, which should do resolve as follows:
.when("/products/search/:page", {
templateUrl: "products.html",
controller: "ProductsSearchController",
resolve: {
// Define all the dependencies here
ProdSearchServ : "ProdSearchService",
// Now define the resolve function
resultData : function(ProdSearchServ) {
return ProdSearchServ.searchProducts();
}
}
})
However, I'm getting the following error
angular.js:9784 Error: [$injector:unpr] Unknown provider: ProdSearchServProvider <- ProdSearchServ
I believe I'm doing most of the things as per conventions, may be I'm missing something here?
I'm copying script.js code below (also in plnkr link above). It has all the route configuration and the controllers defined.
(function(){
// jargoViewer Create a new Angular Module
// This would go into the html tag for index.html
var app = angular.module("jargoViewer", ["ngRoute"]);
app.config(function($routeProvider){
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "NavController"
})
.when("/products/search/:page", {
templateUrl: "products.html",
controller: "ProductsSearchController",
resolve: {
// Define all the dependencies here
ProdSearchServ : "ProdSearchService",
// Now define the resolve function
resultData : function(ProdSearchServ) {
return ProdSearchServ.searchProducts();
}
}
})
.otherwise({redirectTo:"/main"});
});
}());
// Nav Controller
(function() {
var app = angular.module("jargoViewer");
var NavController = function($scope, $location) {
// Function to invoke the Prod search based on input
$scope.search = function() {
console.log("searchText : " + $scope.searchtext);
$location.path("products/search/0").search({searchtext: $scope.searchtext});
};
};
app.controller("NavController", NavController);
}());
// Define the Prod Search Service here
(function() {
// Get reference to the app
var app = angular.module("jargoViewer");
// Create the factory
app.factory('ProdSearchService', function($routeParams, $http, $q) {
var searchProducts = function() {
pageNum = 0;
searchParam = '';
if (('page' in $routeParams) && (typeof $routeParams.page === 'number')) {
pageNum = $routeParams.page;
}
// Check if the router Param contains the field searchtext, if so, check if its a string
if (('searchtext' in $routeParams) && (typeof $routeParams.searchtext === 'string')) {
searchParam = $scope.routeParam.searchtext;
}
// Now make the http API hit to fetch the products
var request = $http({
method: "get",
url: "http://abcd.com/products/search/" + pageNum,
params: {
search: searchParam
},
});
return(request.then(handleSuccess, handleError));
};
function handleError(response) {
// The API response from the server should be returned in a
// nomralized format. However, if the request was not handled by the
// server (or what not handles properly - ex. server error), then we
// may have to normalize it on our end, as best we can.
if (
! angular.isObject(response.data) ||
! response.data.message
) {
return($q.reject( "An unknown error occurred."));
}
// Otherwise, use expected error message.
return($q.reject(response.data.message));
}
// I transform the successful response, unwrapping the application data
// from the API response payload.
function handleSuccess(response) {
if(response.data.error == true) {
return($q.reject(response.data.message));
}
return(response.data.data);
}
return {
searchProducts : searchProducts
};
});
}());
// Define the Products Search Controller below
(function() {
var app = angular.module("jargoViewer");
//var ProductController = function($scope) {
var ProductsSearchController = function($scope, $routeParams, ProdSearchService) {
// Nothing to do really here
};
app.controller("ProductsSearchController", ProductsSearchController);
}());
This caused by your bizarre naming conventions. Sometimes ProdSearchServ and sometimes ProdSearchService.
If you just pick one and use it consistantly then you won't run into these types of errors.
Fixed Plunker
In particular you create the service with the name ProdSearchService and then attempt to use it with a different name:
app.factory('ProdSearchService',
//vs
resultData : function(ProdSearchServ) {
I imagine you we under the impression that this code would fix it for you. However, this only applies to dependencies passed into the controller, not functions in general. For services which already exist, you do not need to define them specially like this; instead simply use the correct name in the controller.
// Define all the dependencies here
ProdSearchServ : "ProdSearchService",
I think you don't need to define the dependency when you say
// Define all the dependencies here
ProdSearchServ : "ProdSearchService",
Just do this:
.when("/products/search/:page", {
templateUrl: "products.html",
controller: "ProductsSearchController",
resolve: {
resultData : function(ProdSearchService) { //as you defined it before
return ProdSearchService.searchProducts();
}
}
})
There is a similar question here

storing dynamic banner images for image slider from remote API before application starting in angularjs

How can I store my banner images from a remote API when ever a angular application starts and maintain that banner images in root scope variable so that it can be accessible in every controller scope.
step-1 create resolve section in router as given below in.
var pcApp = angular.module('pcApp', ['ngRoute', 'ngTouch','ngAnimate']);
pcApp.config(function ($routeProvider) {
c
resolve:{
"check":function($location,$rootScope,$http){
$http.get("http://www.yourdomain.om/frontbanner").success(function (res) {
$rootScope.saveBanner(res.data.details);
}).error();
}
}
}).when('/home', {
templateUrl: 'views/home/home.html',
controller: 'HomeController'
});
});
step-2 -create a function saveBanner in a global js file
pcApp.controller('BodyController', function ($scope, $location, $rootScope) {
$rootScope.banner = {};
if (localStorage.getItem('user_banner')) {
$rootScope.banner = JSON.parse(localStorage.getItem('user_banner'));
}
$rootScope.saveBanner = function (lang) {
$rootScope.banner = lang;
localStorage.setItem('user_banner', JSON.stringify($rootScope.banner));
};
if (localStorage.getItem('user_banner')) {
$rootScope.banner = JSON.parse(localStorage.getItem('user_banner'));
}
});
step-3 -call $roorScope.banner variable where ever its needed.

Passing in a service to ui-router's resolve to avoid making $http requests

I am getting more familiar with ui-router and using .then as opposed to .success. However, I am having some difficulty passing in a service to resolve. Currently, resolve is blocking access to the controller. My goal is to get individual information from each user when they are selected.
I referenced the resolve through the ui-router wiki https://github.com/angular-ui/ui-router/wiki#resolve . Translations 2 seems to resemble how I am using my service
(function() {
'use strict';
angular
.module('app.orders')
.config(config);
function config($stateProvider) {
$stateProvider
.state('orders',{
url:'/customers:customerId',
templateUrl: './components/orders/orders.html',
controller: 'OrdersController',
controllerAs: 'ctrl',
resolve: {
customerFactory: 'customerFactory',
customerId: function( $stateParams, customerFactory) {
return customerFactory.getCustomers($stateParams.id);
}
}
})
};
})();
I am referencing the service call in customerId of resolve This is what I am passing to the ordersController.
Here is my service that is getting my customers.
(function() {
angular
.module('app.services',[])
.factory('customersFactory', customersFactory);
function customersFactory($http, $log, $q) {
return {
getCustomers: getCustomers
};
function getCustomers(){
var defer = $q.defer();
return $http.get('./Services/customers.json',{catch: true})
.then(getCustomerListComplete)
.catch(getCustomerListFailed);
function getCustomerListComplete(response) {
console.log('response.data',response.data);
// defer.resolve(response.data);
return response.data;
}
function getCustomerListFailed(error) {
console.log('error', error);
}
}
}
}());
Here is my controller. It is pretty small for right now. I am hoping to access it first. I do have customerId injected into it however.
(function() {
// 'use strict';
angular
.module('app.orders')
.controller('OrdersController', OrdersController);
function OrdersController($stateParams, customerId) {
console.log(customerId);
var vm = this;
vm.title = "Customer Orders";
vm.customer = null;
}
}());
******* Update *****
I found reviewed some code from when I was using ng-Route.
In this I used $route the same way that I am hoping to use $stateParams.
resolve: {
cityDetails:['cacFindCountry','$route', function(cacFindCountry,$route){
var countryCode = $route.current.params.countryCode;
console.log('cityDetails',cacFindCountry(countryCode))
return cacFindCountry(countryCode);
}],
countryNeighbors : ['cacFindNeighbors','$route', function(cacFindNeighbors,$route) {
var countryCode = $route.current.params.countryCode;
// pushes country code into neighbors
return cacFindNeighbors(countryCode);
}],
countryDetails : ['cacCountries', '$route', function(cacCountries, $route) {
var countryCode = $route.current.params.countryCode;
console.log(countryCode);
console.log(cacCountries(countryCode));
// need to get specific country info
// return cacCountries(countryCode);
return countryCode;
}]
}

Load views after services in angularjs

In my angular app I have a view, a controller and a service.
The service load resources ex:service load persons and initialize value with the result.
I want to load my view after my service finish his function to load his resources.
var myApp = angular.module('myApp',[]);
myApp.controller('PersonsCtrl', ($scope, Persons) {
$scope.persons = Persons.data;
});
myApp.factory('Persons', {
data: [[function that load resources => take time]]
});
So I want to load my controller when my service finish his initialization.
Some ideas?
Assuming you have a route provider, here's a basic example. When the promise is resolved, "personData" will be injected into your controller. There's not much info about what your service does, so I had to give something very generic.
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/persons', {
controller: 'PersonsCtrl',
templateUrl: 'persons.html',
resolve: {
personData: ['Persons', function(Persons) {
return Persons.getData();
}]
}
});
}]);
myApp.controller('PersonsCtrl', ($scope, personData) {
$scope.persons = personData;
});
myApp.factory('Persons', {
getData: function() {//function that returns a promise (like from $http or $q)};
});
Maybe try using promises, example below
var myApp = angular.module('myApp',[]);
myApp.controller('PersonsCtrl', ($scope, Persons) {
$scope.persons = Persons.getData().then(function(response){
//do whatever you want with response
});
});
myApp.factory('Persons', function ($http, $q) {
return {
getData: function () {
var def = $q.defer();
$http.get('url').
success(function (response) {
def.resolve(response);
})
return def.promise();
}
}
});

Inject service in app.config

I want to inject a service into app.config, so that data can be retrieved before the controller is called. I tried it like this:
Service:
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
Config:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
But I get this error:
Error: Unknown provider: dbService from EditorApp
How to correct setup and inject this service?
Set up your service as a custom AngularJS Provider
Despite what the Accepted answer says, you actually CAN do what you were intending to do, but you need to set it up as a configurable provider, so that it's available as a service during the configuration phase.. First, change your Service to a provider as shown below. The key difference here is that after setting the value of defer, you set the defer.promise property to the promise object returned by $http.get:
Provider Service: (provider: service recipe)
app.provider('dbService', function dbServiceProvider() {
//the provider recipe for services require you specify a $get function
this.$get= ['dbhost',function dbServiceFactory(dbhost){
// return the factory as a provider
// that is available during the configuration phase
return new DbService(dbhost);
}]
});
function DbService(dbhost){
var status;
this.setUrl = function(url){
dbhost = url;
}
this.getData = function($http) {
return $http.get(dbhost+'db.php/score/getData')
.success(function(data){
// handle any special stuff here, I would suggest the following:
status = 'ok';
status.data = data;
})
.error(function(message){
status = 'error';
status.message = message;
})
.then(function(){
// now we return an object with data or information about error
// for special handling inside your application configuration
return status;
})
}
}
Now, you have a configurable custom Provider, you just need to inject it. Key difference here being the missing "Provider on your injectable".
config:
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
dbData: function(DbService, $http) {
/*
*dbServiceProvider returns a dbService instance to your app whenever
* needed, and this instance is setup internally with a promise,
* so you don't need to worry about $q and all that
*/
return DbService('http://dbhost.com').getData();
}
}
})
});
use resolved data in your appCtrl
app.controller('appCtrl',function(dbData, DbService){
$scope.dbData = dbData;
// You can also create and use another instance of the dbService here...
// to do whatever you programmed it to do, by adding functions inside the
// constructor DbService(), the following assumes you added
// a rmUser(userObj) function in the factory
$scope.removeDbUser = function(user){
DbService.rmUser(user);
}
})
Possible Alternatives
The following alternative is a similar approach, but allows definition to occur within the .config, encapsulating the service to within the specific module in the context of your app. Choose the method that right for you. Also see below for notes on a 3rd alternative and helpful links to help you get the hang of all these things
app.config(function($routeProvider, $provide) {
$provide.service('dbService',function(){})
//set up your service inside the module's config.
$routeProvider
.when('/', {
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data:
}
})
});
A few helpful Resources
John Lindquist has an excellent 5 minute explanation and demonstration of this at egghead.io, and it's one of the free lessons! I basically modified his demonstration by making it $http specific in the context of this request
View the AngularJS Developer guide on Providers
There is also an excellent explanation about factory/service/provider at clevertech.biz.
The provider gives you a bit more configuration over the .service method, which makes it better as an application level provider, but you could also encapsulate this within the config object itself by injecting $provide into config like so:
Alex provided the correct reason for not being able to do what you're trying to do, so +1. But you are encountering this issue because you're not quite using resolves how they're designed.
resolve takes either the string of a service or a function returning a value to be injected. Since you're doing the latter, you need to pass in an actual function:
resolve: {
data: function (dbService) {
return dbService.getData();
}
}
When the framework goes to resolve data, it will inject the dbService into the function so you can freely use it. You don't need to inject into the config block at all to accomplish this.
Bon appetit!
Short answer: you can't. AngularJS won't allow you to inject services into the config because it can't be sure they have been loaded correctly.
See this question and answer:
AngularJS dependency injection of value inside of module.config
A module is a collection of configuration and run blocks which get
applied to the application during the bootstrap process. In its
simplest form the module consist of collection of two kinds of blocks:
Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants
can be injected into configuration blocks. This is to prevent
accidental instantiation of services before they have been fully
configured.
I don't think you're supposed to be able to do this, but I have successfully injected a service into a config block. (AngularJS v1.0.7)
angular.module('dogmaService', [])
.factory('dogmaCacheBuster', [
function() {
return function(path) {
return path + '?_=' + Date.now();
};
}
]);
angular.module('touch', [
'dogmaForm',
'dogmaValidate',
'dogmaPresentation',
'dogmaController',
'dogmaService',
])
.config([
'$routeProvider',
'dogmaCacheBusterProvider',
function($routeProvider, cacheBuster) {
var bust = cacheBuster.$get[0]();
$routeProvider
.when('/', {
templateUrl: bust('touch/customer'),
controller: 'CustomerCtrl'
})
.when('/screen2', {
templateUrl: bust('touch/screen2'),
controller: 'Screen2Ctrl'
})
.otherwise({
redirectTo: bust('/')
});
}
]);
angular.module('dogmaController', [])
.controller('CustomerCtrl', [
'$scope',
'$http',
'$location',
'dogmaCacheBuster',
function($scope, $http, $location, cacheBuster) {
$scope.submit = function() {
$.ajax({
url: cacheBuster('/customers'), //server script to process data
type: 'POST',
//Ajax events
// Form data
data: formData,
//Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false,
success: function() {
$location
.path('/screen2');
$scope.$$phase || $scope.$apply();
}
});
};
}
]);
You can use $inject service to inject a service in you config
app.config(function($provide){
$provide.decorator("$exceptionHandler", function($delegate, $injector){
return function(exception, cause){
var $rootScope = $injector.get("$rootScope");
$rootScope.addError({message:"Exception", reason:exception});
$delegate(exception, cause);
};
});
});
Source: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
** Explicitly request services from other modules using angular.injector **
Just to elaborate on kim3er's answer, you can provide services, factories, etc without changing them to providers, as long as they are included in other modules...
However, I'm not sure if the *Provider (which is made internally by angular after it processes a service, or factory) will always be available (it may depend on what else loaded first), as angular lazily loads modules.
Note that if you want to re-inject the values that they should be treated as constants.
Here's a more explicit, and probably more reliable way to do it + a working plunker
var base = angular.module('myAppBaseModule', [])
base.factory('Foo', function() {
console.log("Foo");
var Foo = function(name) { this.name = name; };
Foo.prototype.hello = function() {
return "Hello from factory instance " + this.name;
}
return Foo;
})
base.service('serviceFoo', function() {
this.hello = function() {
return "Service says hello";
}
return this;
});
var app = angular.module('appModule', []);
app.config(function($provide) {
var base = angular.injector(['myAppBaseModule']);
$provide.constant('Foo', base.get('Foo'));
$provide.constant('serviceFoo', base.get('serviceFoo'));
});
app.controller('appCtrl', function($scope, Foo, serviceFoo) {
$scope.appHello = (new Foo("app")).hello();
$scope.serviceHello = serviceFoo.hello();
});
Using $injector to call service methods in config
I had a similar issue and resolved it by using the $injector service as shown above. I tried injecting the service directly but ended up with a circular dependency on $http. The service displays a modal with the error and I am using ui-bootstrap modal which also has a dependency on $https.
$httpProvider.interceptors.push(function($injector) {
return {
"responseError": function(response) {
console.log("Error Response status: " + response.status);
if (response.status === 0) {
var myService= $injector.get("myService");
myService.showError("An unexpected error occurred. Please refresh the page.")
}
}
}
A solution very easy to do it
Note : it's only for an asynchrone call, because service isn't initialized on config execution.
You can use run() method. Example :
Your service is called "MyService"
You want to use it for an asynchrone execution on a provider "MyProvider"
Your code :
(function () { //To isolate code TO NEVER HAVE A GLOBAL VARIABLE!
//Store your service into an internal variable
//It's an internal variable because you have wrapped this code with a (function () { --- })();
var theServiceToInject = null;
//Declare your application
var myApp = angular.module("MyApplication", []);
//Set configuration
myApp.config(['MyProvider', function (MyProvider) {
MyProvider.callMyMethod(function () {
theServiceToInject.methodOnService();
});
}]);
//When application is initialized inject your service
myApp.run(['MyService', function (MyService) {
theServiceToInject = MyService;
}]);
});
Well, I struggled a little with this one, but I actually did it.
I don't know if the answers are outdated because of some change in angular, but you can do it this way:
This is your service:
.factory('beerRetrievalService', function ($http, $q, $log) {
return {
getRandomBeer: function() {
var deferred = $q.defer();
var beer = {};
$http.post('beer-detail', {})
.then(function(response) {
beer.beerDetail = response.data;
},
function(err) {
$log.error('Error getting random beer', err);
deferred.reject({});
});
return deferred.promise;
}
};
});
And this is the config
.when('/beer-detail', {
templateUrl : '/beer-detail',
controller : 'productDetailController',
resolve: {
beer: function(beerRetrievalService) {
return beerRetrievalService.getRandomBeer();
}
}
})
Easiest way:
$injector = angular.element(document.body).injector()
Then use that to run invoke() or get()

Resources