How to pass routeProvider attributes to controller - angularjs

I need to setup a controller with some data passed from the routeProvider.
I would like the value topic to be passed to my controller VideoCtrl and then assigned to a value such as video.topic
$routeProvider
.when('/video/:topic', {
templateUrl: 'pages/video/video-page.tmpl.html',
controller: 'VideoCtrl',
controllerAs: 'video'
});
It seems like I should just need to call $routeProvider in my controller function:
app.controller('VideoCtrl', function($routeProvider) {
var video = this;
video.topic = $routeProvider.topic; // What do I need to add here?
...
});
But I can't seem to figure out how to inject $routeProvider into the controller.

I think, you need to pass the $routeParams as controller parameter and then you will able to get the passed route value.
app.controller('VideoCtrl', function($routeParams) {
var video = this;
video.topic = $routeParams.topic;
...
});

Related

Get Id from url() in angular

How to get id from url()This is my url
http://localhost:59113/Project/EditProject?id=2
I did it using jquery..
var url = document.URL;
var id = /id=([^&]+)/.exec(url)[1];
var result = id ? id : ' ';
But I need to do it using angular.Can anyone help me?I tried this too(updated part)
var app = angular
.module("intranet_App", [])
app.config("$routeProvider", function ($routeProvider) {
$routeProvider.when('/view1/:param1/:param2', {
templateUrl: 'Project/EditProject.html',
controller: 'myCtrl'
})
})
.controller("myCtrl", ["$scope", "$http", "$location", "$route", function ($scope, $http, $location, $route) {
// alert($location.id)
var a = $route.current.params;
alert(a.id)
}])
Using $routeParams you can get id,
Updated answer
Use $route instead of $routeParams. Note that the $routeParams are only updated after a route change completes successfully. This means that you cannot rely on $routeParams being correct in route resolve functions. Instead you can use $route.current.params to access the new route's parameters.
$route.current.params
EDIT
You must do this in .config() method
app.config(function($routeProvider){
$routeProvider.when('/view1/:param1/:param2', {
templateUrl: 'Project/EditProject.html',
controller: 'myCtrl'
})
})
$location.search() returns an object, so as per above url
http://localhost:59113/Project/EditProject?id=2
$location.search().id will fetch you an answer.
More Info:
If you are getting an empty object with $location.search(), it is probably because Angular is using the hashbang strategy, To fix this you need to change the following in config file
$locationProvider.html5Mode(true);
$location.search() will return an object of key-value pairs.
in your case:You could access this value directly with $location.search().id

How to change templateURL for angular UI router based on customer settings

I have multiple clients on my angular app and I want to create different themes inside angular (only the visual part will change, controllers remain the same.
I have a "security" module which manages the authentication, currentLoggedIn user and so on.
var security = angular.module('security', ['ui.router'])
// .factory('authService', authService);
.service('authService', ['$http', '$q', '$window', 'CONSTANTS', '$location', 'currentUser', '$state', '$rootScope', authService])
.factory('authCheck', ['$rootScope', '$state', 'authService', securityAuthorization])
and authService is basically having these methods/values
service.login = _login;
service.logout = _logout;
service.reset = _reset;
service.isAuthenticated = _isAuthenticated;
service.requestCurrentUser = _requestCurrentUser;
service.returnCurrentUser = _returnCurrentUser;
service.hasRoleAccess = _hasRoleAccess;
How can I get access to currentUser inside templateURL function to modify the URL based on data for currentUser?
AuthService and AuthCheck are empty when accessed in templateURL function.
$stateProvider
.state('home', {
url: '/home',
templateUrl: function(authService, authCheck) {
console.log (authService, authCheck);
return 'components/home/home.html'
},
data: {
roles: ['Admin']
},
resolve: {
"authorize": ['authCheck', function(authCheck) {
return authCheck.authorize();
}],
"loadedData": ['metricsFactory', 'campaignFactory', '$q', '$rootScope', 'selectedDates', loadHomeController]
},
controller: 'HomeController',
controllerAs: 'home'
});
In case, we want to do some "magic" before returning the template... we should use templateProvider. Check this Q & A:
Trying to Dynamically set a templateUrl in controller based on constant
Because template:... could be either string or function like this (check the doc:)
$stateProvider
template
html template as a string or a function that returns an html template
as a string which should be used by the uiView directives. This
property takes precedence over templateUrl.
If template is a function, it will be called with the following
parameters:
{array.} - state parameters extracted from the current
$location.path() by applying the current state
template: function(params) {
return "<h1>generated template</h1>"; }
While with templateProvider we can get anything injected e.g. the great improvement in angular $templateRequest. Check this answer and its plunker
templateProvider: function(CONFIG, $templateRequest) {
console.log('in templateUrl ' + CONFIG.codeCampType);
var templateName = 'index5templateB.html';
if (CONFIG.codeCampType === "svcc") {
templateName = 'index5templateA.html';
}
return $templateRequest(templateName);
},
From the documentation:
templateUrl (optional)
path or function that returns a path to an html template that should be used by uiView.
If templateUrl is a function, it will be called with the following parameters:
{array.<object>} - state parameters extracted from the current $location.path() by applying the current state
So, clearly, you can't inject services to the templateUrl function.
But right after, the documentation also says:
templateProvider (optional)
function
Provider function that returns HTML content string.
templateProvider:
function(MyTemplateService, params) {
return MyTemplateService.getTemplate(params.pageId);
}
Which allows doing what you want.

Pass specific data from one controller to another

I have a list. What I want is when I click on one of the item of List a new page should open where the data related to only that listItem is displayed. Right now I am using anchor tag and .config to pass data like this:
<ion-item ng-repeat="field in fields">
<a href="#detail/{{field.firstName}}/{{field.personNo}}/{{field.street}}/{{field.city}}/{{field.postcode}}" id="a-item"> <div style="width:100%;height:100%" >
{{field.firstName}}<br>
{{field.personNo}} </div></a>
</ion-item>
And
.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'templates/mainpage.html'
}).
when('/detail/:name/:no/:street/:city/:postcode', {
templateUrl: 'templates/details.html',
controller: 'detailctrl'
})
}])
I don't think this is an effective way to pass data. Although I know about .service but I can't figure out a way to pass data specific to the item clicked. Please suggest a better way. Thanks
What you're looking at is the classic master detail pattern that you indeed would want to use a service (or factory) for.
First change I'll make to your code is giving the main route a controller, as well as for the details route only passing in the personNo.
.config(['$routeProvider',function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'templates/mainpage.html',
controller: 'mainctrl'
}).
when('/detail/:no', {
templateUrl: 'templates/details.html',
controller: 'detailctrl'
})
}])
Next, let's set up a "PeopleService" via a factory with two methods. One, is the GetPeople method which gets all the people in an array and resolves a promise via $http before storing it in a private variable. The GetPerson method looks up a person by personNo in that private variable.
.factory('PeopleService',['$http',function($http){
var people = [];
return {
GetPeople: function(){
$http.get("path/to/resource").then(function(response){
people = response;
return response;
});
},
GetPerson: function(personNo){
for(i=0;i<people.length;i++){
if(people[i].personNo == personNo){
return people[i];
}
}
}
}
}]);
Next, in our mainctrl we will want to call that GetPeople function.
.controller("mainctrl",['PeopleService',function(PeopleService){
PeopleService.GetPeople().then(function(people){
$scope.people = people;
});
}]);
Finally, in our detailsctrl, we will get the personNo from the $routeParams and use it to call the GetPerson method from our service.
.controller("detailctrl",['$routeParams','PeopleService',function($routeParams,PeopleService){
var personNo = $routeParams.no;
$scope.person = PeopleService.GetPerson(personNo);
}]);

How to call a function in AngularJs when route matches?

$routeProvider.when('/ticket', {
controller: TicketController,
templateUrl: Routing.generate('ticket_list')
});
displays a simple list where each entry is selectable. However on select no extra view is loaded. Every thing is in ticket_lost template. The template has some hidden fields that are revealed when entry is clicked.
I can define which entry is selected internally by setting
selectedTicket = 1;
So when there is a route like
/ticket/1
I want to call a function that sets selectedTicket to 1. Is that possible? How to do that? What do I have to change in routing?
Take a look at $routeParams service.
It allows to set up route with parameters which will be parsed by service:
// Given:
// URL: http://server.com/index.html#/ticket/1
// Route: /ticket/:ticketId
//
// Then
$routeParams ==> {ticketId:1}
In your controller:
angular.module('myApp')
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/ticket', {controller: 'TicketController'});
$routeProvider.when('/ticket/:ticketId', {controller: 'TicketController'});
$routeProvider.otherwise({redirectTo: '/ticket'});
}])
.controller('TicketController', function ($scope, $routeParams) {
var init = function () {
if ($routeParams.ticketId) {
$scope.ticketSelected($routeParams.ticketId);
}
};
// fire on controller loaded
init();
});

AngularJS Pre-served $params variables for a controller defined inside of a route

Is it possible to pass your own variables in a defined route in AngularJS?
The reason why I'm doing this is because I have to data representations of the same page (one is a filtered view in terms of the JSON data) and all I need to do is give a boolean flag to the $params array to let the controller function know that this page is either filtered or non-filtered.
Something like this:
var Ctrl = function($scope, $params) {
if($params.filtered) {
//make sure that the ID is there and use a different URL for the JSON data
}
else {
//use the URL for JSON data that fetches all the data
}
};
Ctrl.$inject = ['$scope', '$routeParams'];
angular.modlule('App', []).config(['$routeProvider', function($routes) {
$routes.when('/full/page',{
templateURL : 'page.html',
controller : Ctrl
});
$routes.when('/full/page/with/:id',{
templateURL : 'page.html',
controller : Ctrl,
params : {
filtered : true
}
});
}]);
According to $routeProvider documentation, the route parameter of $routeProvider.when() has property resolve:
An optional map of dependencies which should be injected into the controller.
Something like this should work:
function Ctrl($scope, isFiltered) {
if(isFiltered) {
//make sure that the ID is there and use a different URL for the JSON data
}
else {
//use the URL for JSON data that fetches all the data
}
}
Ctrl.$inject = ['$scope', 'isFiltered'];
angular.modlule('App', []).config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/full/page',{
templateURL: 'page.html',
controller: Ctrl
});
$routeProvider.when('/full/page/with/:id',{
templateURL: 'page.html',
controller: Ctrl,
resolve: {
isFiltered: function() { return true; }
}
});
}]);
AFAIK it is not currently possible to specify additional parameters for a route. Having said this your use case could be easily covered by testing if :id is defined as part of $routeParams.
The thing is that AngularJS will match your routes either on '/full/page' or '/full/page/with/:id' so just by testing $routeParams for id presence in your controller:
if ($routeParams.id)
you would know in which case your are.
The alternative is to use different controllers for different routes.
mething like this must be work for filter:
function caseFilterCtrl($scope, $routeParams, $http) {
$http.get('./data/myDatas.json').success( function(data){
var arr = new Array();
for(var i=0; i < data.length; i++){
if(data[i].filter == $routeParams.id){
arr.push(data[i]); }
}
$scope.filtered= arr;
});
}
caseFilterCtrl.$inject = ['$scope', '$routeParams', '$http']; //for minified bug issue
and the routage :
angular.module('myFilterApp', []).
config(['$routeProvider', function($routeProvider){
$routeProvider.when('/filter/:id', {templateUrl: './view/partial/filter.html', controller: caseFilterCtrl});
$routeProvider.otherwise({redirectTo: '/filter/01'});
}
]);
You can get sneak params directly through $route.current.$$route.
function Ctrl($scope, $route) {
var filtered = $route.current.$$route.params.filtered;
}
angular.modlule('App', []).config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/full/page/with/:id',{
templateURL: 'page.html',
controller: Ctrl,
params : {
filtered : true
}
});
}]);
Although it work, I'd still prefer a resolve solution. params (or any name of your choice) could be overwritten by angularjs in future releases.

Resources