$http request in angular config - Is it possible? - angularjs

I am trying to make an $http call inside my publicApp.config in order to retrieve an array of available routes to match with the $urlMatcherFactoryProvider.
Right now, I am hard-coding them to be pageUrls = ['about','contact','another-page'];
But I have an url in my express API which returns an array of available URLS. The api URL is "/page-urls"
Would it be possible to make an $http.get('/page-urls') request inside the config? I know $http is available inside run(), but I need the list of available URLs BEFORE routing via the $stateProvider.
(function() {
'use strict'
var pageUrls = [];
var publicApp = angular.module('publicApp', ['ui.router'])
publicApp.config(['$stateProvider', '$urlRouterProvider', '$urlMatcherFactoryProvider', function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
pageUrls = ['about','contact','another-page'];
var urls = pageUrls.join('|');
var urlMatcher = $urlMatcherFactoryProvider.compile("/{source:(?:" + urls + ")}");
$stateProvider
.state('/', {
url: '/',
templateUrl: "views/home/home.view.html",
controller: "homeCtrl"
})
.state('urls', {
url: urlMatcher,
templateUrl: "views/pages/page.view.html",
controller: "pageCtrl"
});
$urlRouterProvider.otherwise('/');
}]);
})();

Create a provider which gets $stateProvider as an injectable. The provider will create a service that does the http request then registers the routes. Inject the service in a run block and initiate route registration.
Something like this:
var publicApp = angular.module('publicApp', ['ui.router'])
publicApp.provider('routes', function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider){
function registerRoutes(listOfUrls){
// register routes with $stateProvider
// angular.forEach(listOfUrls, function(url){
// $stateProvider.state...
// });
}
this.$get = function($http){
return {
initialize: function(){
return $http.get('/page-urls').then(function(response){
registerRoutes(response.data);
});
}
};
};
});
publicApp.run(function(routes){
routes.initialize();
});

Related

StateProvider somewhere else than app.js in AngularJS

I'd like to know if I can put a stateprovider somewhere else than my app.js, because it causes me some problems in other pages.
app.js
var app = angular.module('myApp', 'ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: 'templates/step_Form/form.html?v=' + new Date().getDay()
})
// url will be nested (/form/profile)
.state('form.upload', {
url: '/upload',
templateUrl: 'templates/step_Form/form-upload.html?v=' + new Date().getDay()
})
// url will be /form/interests
.state('form.content', {
url: '/content',
templateUrl: 'templates/step_Form/form-content.html?v=' + new Date().getDay()
})
$urlRouterProvider.otherwise('/form/upload');
})
My controller
angular.module('myApp').controller('ImportGeneralCtrl', function ($scope, $stateProvider, $urlRouterProvider) {
//myfunctions
}
I integrated a multi-step form in my HTML, using the state provider.
How could i get out the state provider from app.js to only apply it on my controller?
You cant use $stateProvider or $urlRouterProvider (providers) in a controller because those providers are just made for configuration injection. It can be uses in any angular.module('myApp').config() you want but you can't user providers in a controller. In controllers you could only inject $state (modules, services, factories, e.g.):
angular.module('myApp').controller('myController', function ($scope, $state) {}
This little code snippet shows you how to create a Service, a Factory and a Provider.

Pass parameter from Angularjs controller to $stateProvider

This is my Angularjs .config file that opens lead.html page whenever 'tasks' is activated from another html using ui-router.
App
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
$stateProvider
.state('tasks', {
templateUrl: {{name}}.html,
controller:"TasksController"
});
}]);
This is my Taskscontroller.js
App
.controller(
"TasksController", [function($scope, $http,$window) {
var self = this;
self.name = 'lead'; // I wanna use this parameter in templateUrl
console.log("In tasks Controller");
}]);
I want to make the templateUrl take parameter from TasksController so that it redirects to relevant page based on the parameter set in TasksController.
Please guide me how to do this.
Thanks
You could try using $stateParams:
App.config(['$stateProvider', '$urlRouterProvider', '$stateParams', function($stateProvider, $urlRouterProvider, $stateParams) {
$stateProvider
.state('tasks', {
params: {
page: null
},
templateUrl: {{$stateParams.page}}.html,
controller: "TasksController"
});
}]);
Then in your controller:
App.controller("TasksController", [function($scope, $http, $window, $stateParams, $state) {
var self = this;
self.$stateParams.page = 'some_url.html';
self.$state.go('tasks');
}]);
Don't forget the injection in the controller too. Haven't tested this but you may need the $state go like this:
self.$state.go('tasks', { page: 'some_url.html' }, { });

Setting AngularJS app configurations after a service has been called

I am using $urlRouterProvider service in my app.config to define the default routes in my AngularJS application. I define it as follows:
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when('/', '/history')
.otherwise('/history');
$stateProvider
.state('tabs', {
abstract: true,
url: '/',
template: '<my-tab></my-tab>',
onEnter: function(){console.log("enter");}
})
});
My problem is that I want to set these routes after a Boolean variable flag is fetched from database using a custom service (databaseService). If the flag is true, it should be:
$urlRouterProvider
.when('/', '/history')
.otherwise('/history');
and if flag is false, it should be:
$urlRouterProvider
.when('/', '/future')
.otherwise('/future');
How can I achieve this? I am not able to use a custom service in app.config function. Also I can't set configurations in my service because config gets set before a service is loaded. Please help!
Assuming you're going to change this once at the start of the application you could to the following (docs):
var routerProvider = null; // reference router for run phase
angular
.module('app')
.config(config)
.factory('databaseService', databaseService)
.run(run);
config.$inject = ['$urlRouterProvider'];
run.$inject = ['$urlRouter', 'databaseService'];
function config($urlRouterProvider) {
$urlRouterProvider.deferIntercept();
routerProvider = $urlRouterProvider;
}
function databaseService() {
return {
getDbFlag: function() {
// connect to db and fetch data
}
};
}
function run($urlRouter, databaseService) {
databaseService.getDbFlag()
.then(function (serviceData) {
// set the route with data from the DB
routerProvider.otherwise(serviceData.route);
$urlRouter.sync();
$urlRouter.listen();
});
}

How to pass initialization data to angular module?

I have a webmethod on my remote server returning a JSon object.
Said json object contains strings which are required for the module to proper work.
So, is there a way to pass something to an angular module?
An idea could be to perform an http request inside of the initialization of the module:
$scope.init = function(){
$http.get ()
...
then(){
$scope.mydata = result;
}
};
But that would be asynchronous...
If you are worried about the async nature of an HTTP request to fill out your $scope.mydata variable, then you need to include this in a RESOLVE in your route.
I'm using UI-ROUTER in my current project:
(function() {
'use strict';
angular
.module('capps.core')
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home.capps', {
url: '/',
template: '<ui-view/>',
data: {
requireLogin: true
},
resolve:{
resolveFunction: resolveFunction
}
});
}
]);
resolveFunction['$inject'] = ['$http'];
function resolveFunction($http) {
return $http.get(API_URL)
.then(function(res) {
console.log(res);
});
}
})();
Then in your controller, you can pass 'resolveFunction' as a dependency... then use that to assign to your $scope.myData.
...
angular.controller('myController', myController);
myController.$inject = ['resolveFunction', '$scope'];
function myController(resolveFunction, $scope) {
$scope.mydata = resolveFunction.data;
console.log(mydata);
};

AngularJS UI router - Pass angular object to ui-router controller method?

I want to pass the data of the function PhoneList() to the UI-Router controller function to the state 'phonedescription'.
JS:
var myApp = angular.module('myApp', ["ui.router"]);
myApp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/phone")
$stateProvider
.state('phone', {
url: "/phone",
templateUrl: "index.html"
})
.state('phonedescription', {
url: "/description",
templateUrl: "description.html",
controller: function($scope){
//Want to access the angular object to pass the attributes to this controller
}
}
});
function PhoneList($scope, $http, $templateCache)
{
$scope.list = function() {
$scope.phones = //get data from backend
}
$scope.list();
};
It appears that you are defining PhoneList as a loose function outside of the angular framework. Look into using a service instead. You can then inject that service into your phonedescription controller.

Resources