Dynamic routeProvider parameters for angular router - angularjs

I am trying to take advantage of the back button's history, and so I am using the traditional $routeProvider and a url of
.../arg1/something/arg2/something,else/arg3/another/arg4/yet,another/arg5/final
However, if one argument is missing, the following route provider will fail to pass the remaining arguments to the $routeParams:
angular.module('myApp', [ … ])
.config(function ($routeProvider) {
$routeProvider
.when('/arg1/:args1/arg2/:args2/arg3/:args3/arg4/:args4/arg5/:args5', {
templateUrl: 'views/main.html',
controller: 'MainController'
})
.otherwise({
redirectTo: '/'
});
});
How do I configure the $routeProvider to pass the arguments that are present, (in any order if possible, if not at least in the order that but account for absence of an argument), to the controller without having to declare all 720 (6!) different scenarios of different arguments in different order or not at all?
I then plan to use these values to populate the filters in the controller via the following:
function filterRouteParams (rp){
if(rp.args1){
$scope.args1 = rp.args1;
}
if(rp.args2){
$scope.args2 = rp.args2.split(',');
}
if(rp.args3){
$scope.args3 = rp.args3.split(',');
}
…
}
I am a little familiar with using the ? query on the URL, but to my knowledge, I don't know how to bind that to the history when I want to update it and also allow for using the back button and maintain the query, but am open to being schooled!

Do I not understand ur question, or it just got complicated?
You just SIMPLY use query string for this purpose.
It works perfectly fine with back and forward buttons, history push/state.
angular.module('myApp', ['ngRoute'])
.controller('MainController', function($scope, $route, $routeParams, $location) {
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
})
.controller('FilterController', function($scope, $routeParams) {
})
.config(function($routeProvider) {
$routeProvider
.when('/filter', {
template: 'inside filter',
controller: 'FilterController'
})
.otherwise({
redirectTo: '/filter'
});
});
This is the running example of the above code, http://run.plnkr.co/plunks/OS38E38J11FeDS1hyHde/#/filter?c=3&d=4
and Here is the plnkr.

I think the best way of handling this is through query string parameters, so your route is defined like this:
.when('/filter', {
controller: 'MainController'
})
And you just use a URL like /filter?foo=44&bar=123&baz=true, or in code:
$location.path('/filter').search('foo', $scope.fooValue).search('bar', $scope.barValue);
Parameters are optional and be specified in any order as ngRoute does not do any validation of param names or values.
To access the values in your controller:
.controller('MainController', function($scope, $routeParams) {
if ($routeParams.foo) {
// do argument processing
}
})
docs for $routeParams: https://docs.angularjs.org/api/ngRoute/service/$routeParams

I'm not sure to really understand, but could you use '?' inside your routes ? for example
$routeProvider
.when('/arg1/:args1?/arg2/:args2?/arg3/:args3?/arg4/:args4?/arg5/:args5?', {
templateUrl: 'views/main.html',
controller: 'MainController'
})
.otherwise({
redirectTo: '/'
});
Any of the following URL would be valid
/arg1/arg2/arg3/arg4/arg5
/arg1/value1/arg2/arg3/arg4/arg5/value5
....
/arg1/value1/arg2/value2/arg3/value3/arg4/value4/arg5/value5
Is that what you were looking for?
Unfortunately I couldn't find a way to remove an argument like this
/arg1/arg2/arg4/value4/arg5/value5

Related

angular js $routeParam not working properly

i have used $routeProvide to redirect page from one page to another and in that i am passing some dynamic parameters in url.
it working at one place and not working with another place.
my code : in app.js
app.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: "client/home/home.html",
controller: "IndexCtrl",
access: {
isloggedIn: false
}
})
.when('/test/:searchTerm', {
templateUrl: "client/test.html",
controller: "testController",
access: {
isloggedIn: false
}
})
.when('/test2/:id', {
templateUrl: "client/index.html",
controller: "indexController",
access: {
isloggedIn: true
}
})
.otherwise({
redirectTo: "/"
});
}]);
in controllers file : for testController when i hit url
server.com/#/test/45 got in console 45 and for indexController when i hit url server.com/#/test2/45 then i get :id in console.
app.controller("testController", ['$location', '$rootScope', '$routeParams', function ($location, $rootScope, $routeParams) {
console.log($routeParams.searchTerm); //get result 45
}]);
app.controller("indexController", ['$location', '$rootScope', '$routeParams', function ($location, $rootScope, $routeParams) {
console.log($routeParams.id); //get result :id
}]);
why this happen can anyone help? and what should be the issue?
Try ($routeParams.id); instead of ($routParams.id);, I don't know why your $routParams.searchTerm is working, but it shouldn't (should be route, not rout).
Seems like your code is correct, other than the spelling mistake. The only difference i can find is that the IsLoggedIn property value. Did you try by making it false?. And what is the significance of IsLoggedIn property.
check your hyperlink to the route /test2/:id.
It may be like ng-href="#/test2/:id"
change it to ng-href="#/test2/{{id}}"
don't forgot to define variable id
recreated the issue in fiddle

how to implement Rooting angularJS with customize url

I want to have on the URL of my application like this:
http://localhost:9000/#/?id=XYZ
I don't found how to configure this on angularjs app module
My implementation is like that:
angular.module('APP', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when("/?id="+":id", {
templateUrl: "views/sign/sign.html",
controller: "SignCtrl"
});
// $locationProvider.html5Mode(true);
});
but It doesn't work.
You do not have to specify
it will be like
angular.module('APP', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when("/", {
templateUrl: "views/sign/sign.html",
controller: "SignCtrl"
});
// $locationProvider.html5Mode(true);
});
and in your SingCtrl.
when you write $routeParam than you will have objects of params which are passed as a query parameter.
so you will get $routePara.id if you pass like ?id=anything
Do not have to worry if you want to catch the query param like ?id=abs&name=test
You can add a "url" attribute to your $routeProvider object.
Something like:
$routeProvider.when("/?id="+":id", {
templateUrl: "views/sign/sign.html",
url: 'the Url you want to use',
controller: "SignCtrl"
});
PS.: I suggest you to use ui-router instead of ngRoute. Check it out later.

Angular ui.router. Deep nested routes

Here is an example to check http://embed.plnkr.co/uVMlkk/preview
When we navigate to 'page2' route there is a 'hey, I'm a subroute' note.
But once we navigate anywhere else that note will disappear forever.
The goal is to make some nested states to be shown right away (as a default ones).
I assume there should be some cases using $state.go(), but can't figure it out so far. Any help is highly appreciated.
State definition snippet:
.state('root.page2.tab', {
url: '/:tabId',
templateUrl: 'tpl.page2.tab.html',
controller: 'Page2TabController'
})
.state('root.page2.tab.subroute', {
url: '',
templateUrl: 'tpl.page2.tab.subroute.html'
})
the content of the 'tpl.page2.tab.subroute.html':
hey, I'm a subroute
related controller:
.controller('Page2TabController', ['$scope', '$state', function($scope, $state) {
$scope.tabId = $state.params.tabId;
$state.go('root.page2.tab.subroute');
}])
There is a fixed version.
I removed the url from the 'root.page2.tab.subroute'
.state('root.page2.tab.subroute', {
//url: '',
templateUrl: 'tpl.page2.tab.subroute.html'
})
And because the parent has defined paramater tabId:
.state('root.page2.tab', {
url: '/:tabId',
templateUrl: 'tpl.page2.tab.html',
controller: 'Page2TabController'
})
We have to pass that param inside of the redicrection:
.controller('Page2TabController', ['$scope', '$state', function($scope, $state) {
$scope.tabId = $state.params.tabId;
// instead of this
// $state.go('root.page2.tab.subroute');
// we need this
$state.go('root.page2.tab.subroute', $state.params);
}])
Check the working, fixed version here
ANOTHER approach - using redirectTo - there is a working plunker
One way, inspired by this:
Redirect a state to default substate with UI-Router in AngularJS
could be to add a very smart but small redirect code snippet:
.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(evt, to, params) {
if (to.redirectTo) {
evt.preventDefault();
$state.go(to.redirectTo, params)
}
});
}])
And adjust our state like this:
.state('root.page2.tab', {
url: '/:tabId',
templateUrl: 'tpl.page2.tab.html',
controller: 'Page2TabController',
redirectTo: 'root.page2.tab.subroute',
})
Check it here
There is a trick how to handle scenarios:
Parent should trigger some action in case that
it is accessed, or
its reached again, when navigating back from child in a parent state
In that case, we can use the "target (ui-view) for a child" as a place where sits the special view, with special controller. This will be
injected into that position once parent is created and
re-injected into that position again, once child is left. In that case, it will be re-init.
Enough explanation. There is a working plunker. There is adjusted state:
.state('root.page2', {
url: '/page2',
views: {
'content#root': {
templateUrl: './tpl.page2.html',
controller: 'Page2Controller'
},
'#root.page2': {
template: '<div></div>',
controller: 'RedirectorController'
}
}
})
So, now we can do some magic inside of our 'RedirectorController'
.controller('RedirectorController', ['$scope', '$state',
function($scope, $state) {
$state.go('root.page2.tab', { tabId: $scope.activeTabId });
}])
Check it in action here
Read more about what that new view/controller get from the other (Scope Inheritance by View Hierarchy Only) one here
Nested states or views for layout with leftbar in ui-router?
How do I share $scope data between states in angularjs ui-router?

$routeProvider - where is the var passed to .when stored

I am an amateur with angular. I am using route provider to load separate html pages and controllers. This works fine when I know what pages the site has and I can define them.
app.config(function($routeProvider) {
$routeProvider
.when("/page1", {
templateUrl: "../page1.html",
controller: "Page1Ctrl"
})
.when("/page2", {
templateUrl: "../page2.html",
controller: "Page2Ctrl"
})
.when("/page3", {
templateUrl: "../page3.html",
controller: "Page3Ctrl"
})
.otherwise({
redirectTo: "/page1"
});
});
However, in future, more pages may be added and I want to code a way for angular to take this into accout. Something like;
app.config(function($routeProvider) {
(..figure out n...)
$routeProvider
.when("/page"+n, {
templateUrl: "../page"+n+".html",
controller: "Page"+n+"Ctrl"
})
.otherwise({
redirectTo: "/page1"
});
});
I cannot figure out how to return a var listing the current page so I can remove '/page' to manipulate the int as n.
I tried console logging $routeProvider but .when simply returns a function. I don't think injecting $scope is wise because obviously a var is passed somewhere using $routeProvider alone.
If you use colon (:) in the route, Angular will parse that and populate the $routeParams with it, then, in your templateUrl, instead of a string, you can use a function which returns the template url. Just inject the $routeParams in the templateUrl's function and build the url you need.
$routeProvider
.when( '/page/:pageNumber', {
templateUrl: function ($routeParams) {
return 'page_' + $routeParams.pageNumber + '.html'
}
})
.otherwise( { redirectTo: '/page/1' } );
Here is a working fiddle.

$routeParams not defined. I am not sure what I changed to make it not work suddenly

I am not sure what is going on here.
angular.module('myApp', [
'ngRoute',
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: '/partials/homepage',
controller: 'MyCtrl1'
}).
when('/about/:id', {
templateUrl: '/partials/'+$routeParams.id,
controller: 'MyCtrl1'
}).
when('/funnel', {
templateUrl: '/partials/funnel',
controller: 'MyCtrl2'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
No matter if I browse to / or /about/:id I get $routeParams is undefined.
You need to inject $routeParams service to use it. However in your case looks like you want to dynamically determine the template based on the routeparam. You cannot directly do it in the config phase of the app, which runs only once as a part of app initialization stage (and also you can inject $routeParams in the config phase of the app since there is no such provider). You you may want to look for a way to retrieve dynamic template and in order to support this angular provides this facility to use function as templateUrl to be able to dynamically determine the template url based on any routeparameters (which will be argument in the function).
You can do it this way:-
when('/about/:id', {
templateUrl: function(routeParam){ //register it as function
return '/partials/' + routeParam.id; //Get the id from the argument
},
controller: 'MyCtrl1'
}).
Right from documentation.
templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.
If templateUrl is a function, it will be called with the following parameters:
{Array.<Object>} - route parameters extracted from the current $location.path() by applying the current route
It's because of this line:
templateUrl: '/partials/'+$routeParams.id,
You're using $routeParams without every declaring or injecting it. If you add it to the params your function accepts, your page should stop throwing that error:
config(function ($routeProvider, $routeParams, $locationProvider) {
// ...
}

Resources