I'm trying to configure my AngularJS app with optional route parameter.
The URLs that I need to support may have a locale at the beginning. e.g.
/fr-FR/Welcome
/Welcome
I tried the following
$routeProvider.when('/:locale?/Welcome', {
...
})
However, it seems, it satisfies the "/fr-FR/Welcome" case and not the "/Welcome" case.
Is it because I'm always prepending a "/" in the beginning.
Will the following work?
$routeProvider.when('/:locale/?Welcome', {
...
})
https://docs.angularjs.org/api/ngRoute/service/$route#example
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
}
})
.when('/Book/:bookId/ch/:chapterId', {
templateUrl: 'chapter.html',
controller: 'ChapterController'
});
Also you can use for multiple language support like this tutorials
https://scotch.io/tutorials/internationalization-of-angularjs-applications
It is not possible in Angular.
remember /:locale is not optional. it is route parameter which means its value could be different but it should be there to execute that route (controller and template).
like
/fr/Welcome
/en/Welcome
fr and en must be there which help angular to select that route.
Related
I'm working on multiple angular apps that I have to nest (like a web portal). My main app got a router where I define some states.
$stateProvider
.state('state1', {
url: "/state1",
views: {
"area": { templateUrl: "area1.html"}
}
});
And my other apps work like this too. I'd like to make a specific script that would be called if the state called in the main app is unknown by the main router, so I could to get the url and views in another router.
For example, if the main app call the state state2 that is unknown by my first router, it will look for it in a second router which define it.
I looked for a solution using the resolve option of ui-router but I'm not sure it could work this way.
Feel free to ask for more details. I did my best to make it short and understandable :)
Documentation on Otherwise()
app.config(function($urlRouterProvider){
// if the path doesn't match any of the urls you configured
// otherwise will take care of routing the user to the specified url
$urlRouterProvider.otherwise('/index');
// Example of using function rule as param
$urlRouterProvider.otherwise(function($injector, $location){
... some advanced code...
});
})
Hope this code help you as your need:
var myApp = angular.module('myApp', []);
myApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/state1');
$urlRouterProvider.when("", "/state1");
$stateProvider
.state('state1', {
url: '/state1',
templateUrl: 'state1.php'
}
})
.state("state2", {
url: "/state2",
templateUrl: 'state2.php'
});
});
So, the workflow with angularjs $routeProvider goes as following,
$routeProvider
.when('/main1', {
templateUrl: 'view1.html',
})
.when('/main2', {
templateUrl: 'view2.html',
})
My question is, is there any way of simplifying the following code. If when('/main1') and when('/main2') point to the same template. So,
$routeProvider
.when('/main1', {
templateUrl: 'view1.html',
})
.when('/main2', {
templateUrl: 'view1.html',
})
The question is asked because if we have multiple languages on the site, and we want to have multiple translations of the url.
Another solution would be to recognize if the site is using .com or .de for instance, and thus adjust to the correct /main1 or /main2 translation. So for instance,
var url = window.location.href;
var main;
if (url.match(/.de/) !== null){
main = "/main1";
}else{
main = "/main2";
}
$routeProvider
.when(main, {
templateUrl: 'view1.html',
})
But semantically, this doesn't seem to be the best solution as I like to keep configuration options set in the run block after the config. We also can't inject factories (only providers, I may be mistaken though) to config.
I would go for putting the language as first url segment in the route.
$routeProvider.when('/:lng/main', {
templateUrl: 'main.html',
controller: function($routeParams){
var lng = $routeParams.lng;
}
})
Though it would be really nice if the $routeProvider would provide this functionality where the an url segment can be isolated. I ain't that pretty putting :lng in each route.
I need to change an existing AngularJS application from using URLs in the format:
example.com/thePage/#/section/1/subsection/1
To making the section & subsection parameters readable by the server with a format like so:
example.com/thePage?section=1&subsection=1
The environment does not offer something like mod_rewrite, so I need to change the routing in Angular to make it handle & generate these URLs. I believe I can do this using $locationProvider.html5Mode(true); however I’m not sure how to proceed from there. I’ve tried updating the existing routing to something like the below, however it fails to return a view (as if the routing isn’t working.
$stateProvider
.state('section', {
abstract: true,
url: '?section',
views: {
'header': {
template: '<h3></h3>'
},
'main': {
templateUrl: constants.baseUrl + 'views/section.html',
controller: 'sectionCtrl',
resolve: {
section: ['sectionervice', '$stateParams',
function (sectionervice, $stateParams) {
return sectionervice.getsection($stateParams);
}],
subsection: ['sectionervice', '$stateParams',
function (sectionervice, $stateParams) {
return sectionervice.getsubsection($stateParams);
}]
}
}
}
})
.state('section.detail.subsection', {
url: '&subsection=:sectionId',
views: {
'main': {
templateUrl: constants.baseUrl + 'views/section.detail.subsection.html',
controller: 'DictionaryCtrl'
}
}
});
It seems that $stateProvider may only work with the forward-slash(/) parameter delimiter. Is there another way to achieve this?
In the ui-router website has a simple example of you trying to do.
Maybe you can do the same thing, see the RouteProvider and StateProvider settings.
url: http://angular-ui.github.io/ui-router/sample/app/app.js
In the server side you can retrieve the url, so you can get your parameters.
[Edit]
About $locationProvider.html5Mode(true); you can do this and do the settings in route and state providers too, that don't interfere in functionality
I'm working on a file editing application in AngularJS. My urls look like this:
#/fileName.md
or
#/folder/fileName.md
or
#/folder/nested-folder/another-folder/itgoesonforever/filename.MD
I don't want to have to do a route for every single depth and it could be ~15 routes deep. Are there any ways to have conditional routes? Crudely:
/:fileorfolder?/:fileorfolder?/:fileorfolder?/:fileorfolder?
I think the best you can do with Angular is *, which is new as of v1.1.5 of $routeProvider:
path can contain named groups starting with a star (*name). All characters are eagerly stored in $routeParams under the given name when the route matches.
For example, routes like /color/:color/largecode/*largecode/edit will match /color/brown/largecode/code/with/slashes/edit and extract:
- color: brown
- largecode: code/with/slashes
You'd have to parse the largecode param yourself though.
I think I got it! The trick is to set the template to a simple , then modify the scope to include the dynamic path to your template.
So now I can place a file at /foo/bar/baz.html and see the template rendered by going to server.com/foo/bar/baz.
// Routes
app.config( function($routeProvider) {
$routeProvider
// Home
.when( '/', {
templateUrl: 'home.html',
controller: 'HomeController'
})
// Catch All
.when( '/:templatePath*', {
template: '<ng-include src="templatePath"></ng-include>',
controller: 'CatchAllCtrl'
})
});
// Catch All Controller
app.controller("CatchAllCtrl", function($scope, $routeParams) {
$scope.templatePath = $routeParams.templatePath + '.html';
});
You could look at using the routeProvider#otherwise functionality
$routeProvider
.otherwise({controller: 'FileEditor',...});
http://docs.angularjs.org/api/ng.$routeProvider
I'm working on a web page that is using Angular, jQuery Mobile, and the jQuery Mobile Angular adapter by tigbro. I have everything up an running and it works great except for one issue and that is if at any point if you refresh the page using the browser's refresh button it will give a 404 error as if it doesn't understand the route anymore. I'm not sure where the issue might be since it gets a little confusing with the two frameworks and the adapter working together and I'm new to all of these technologies.
IE happens to be the only browser this doesn't happen in and the difference seems to be in the url. Here is what it looks like when you browse to a page in IE:
http://site.com/SalesManagement/SalesManagementIndex.aspx#!/ViewNotes/4
Here is what it looks like when you browse to the same page in another browser like Chrome:
http://site.com/SalesManagement/ViewNotes/4
If you go to the first url in Chrome it will load the page and then rewrite the url to the 2nd one.
Below is my routing configuration:
var SalesManagementApp = angular.module('SalesManagementApp', [])
SalesManagementApp.config(['$routeProvider', '$compileProvider', function ($routeProvider, $compileProvider) {
$routeProvider
.when('/Search', { templateUrl: 'Views/GrowerSearchView.aspx' })
.when('/SearchResults', { templateUrl: 'Views/GrowerResultsView.aspx' })
.when('/ViewNotes/:growerIndexKey', { templateUrl: 'Views/NotesHistoryView.aspx' })
.when('/EditNote/:growerIndexKey/:noteIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/AddNote/:growerIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/', { templateUrl: 'Views/GrowerSearchView.aspx' })
.otherwise({ templateUrl: 'Views/GrowerSearchView.aspx' });
} ]);
I've read some about html5 mode verse hashbang mode but setting html5 mode to off or on in the configuration just made my routing not work at all. Any help would be much appreciated.
I figured this out thanks to a similar question on the github site for the adapter: https://github.com/opitzconsulting/jquery-mobile-angular-adapter/issues/163
The fix for this is to disable html5Mode in angular and prefix your links with the # character. This makes your urls a little uglier as you are no longer using the html5 history API but in my case that doesn't matter. Optionally you can specify a hash prefix (by default it seems to be !) but I set mine to empty string. I couldn't find any documentation telling me why this is useful but its important to know what the prefix is so you can properly set your links.
Below is my updated routing configuration. Notice I now inject the $locationProvider.
var SalesManagementApp = angular.module('SalesManagementApp', [])
SalesManagementApp.config(['$routeProvider', '$compileProvider', '$locationProvider', function ($routeProvider, $compileProvider, $locationProvider) {
$locationProvider.html5Mode(false).hashPrefix("");
$routeProvider
.when('/Search', { templateUrl: 'Views/GrowerSearchView.aspx' })
.when('/SearchResults', { templateUrl: 'Views/GrowerResultsView.aspx' })
.when('/ViewNotes/:growerIndexKey', { templateUrl: 'Views/NotesHistoryView.aspx' })
.when('/EditNote/:growerIndexKey/:noteIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/AddNote/:growerIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/', { templateUrl: 'Views/GrowerSearchView.aspx' })
.otherwise({ templateUrl: 'Views/GrowerSearchView.aspx' }); // jQuery Mobile seems to ignore the / and just use .otherwise.
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
if (!localStorage.SessionInfo)
window.location = '/Login.aspx';
} ]);
My links now look like: #/ViewNotes/{{growerIndexKey}}