I'm trying to create a route to the profile page of a user, which must be "/:username", but it doesn't work. It is described on the last line. It seems that the child routes don't work with parents that have an empty path.
app.js
configureRouter(config, router){
config.title = 'Dreampper';
//config.options.pushState = true;
config.map([
{ route: '', moduleId: 'home'},
{ route: 'login', moduleId: './components/account/login', name: 'login'},
{ route: 'register', moduleId: './components/account/register', name: 'register'}
]);
In my home.js I have:
{ route: '', moduleId: './components/timeline/timeline', name: 'timeline' },
{ route: 'welcome', moduleId: './components/account/welcome', name: 'welcome' },
{ route: 'account/EmailConfirmation/:user/:code', moduleId: './components/account/email-confirmation', name:'Email confirmation' },
{ route: ':username', moduleId: './components/profile/profile', name: 'profile' }
Someone could help me? I don't want to use redirect, because the redirect makes the URL doesn't be empty "localhost/".
Use the mapUnknownRoutes function when you configure your router. I didn't test this but you should be able to do something like this. Please also take into account Fabio's suggestion -- it's a good one. But if you really want to do it...
config.mapUnknownRoutes({ redirect: '#/' });
router.configure(config => {
config.mapUnknownRoutes(instruction => {
//check instruction.fragment
//set instruction.config.moduleId
});
});
Basically you'll want to look at the instruction.fragment to get the actual route that was specified, and then redirect it to a particular route with the parameter as whatever route was given.
Related
I have a main App router and multiple child routers. I'd like to have the option of specifying the child route to open when navigating from the parent route.
Parent Router:
configureRouter(config, router) {
this.router = router;
config.map([
{ route: ['','home'], name: 'home', moduleId: 'home/home' },
{ route: 'students/:id?', name: 'students', moduleId: 'students/students' },
{ route: 'staff', name: 'staff', moduleId: 'staff/staff' }
]);
}
Child Router for Students:
export class Students {
configureRouter(config, router) {
config.map([
{ route: ['', 'home'], name: 'student-home', moduleId: 'students/students-home' },
{ route: 'list', name: 'student-list', moduleId: 'students/student-list' },
{ route: 'profile/:id', name: 'student-profile', moduleId: 'students/profile/overview' },
{ route: 'lockers', name: 'student-lockers', moduleId: 'students/lockers/home' }
]);
this.router = router;
}
activate(params) {
if (params.id) {
console.log("Going straight to a student record for: ", params);
this.router.navigateToRoute('student-profile', {id: params.id});
}
}
}
The above scenario (using navigateToRoute() within activate) doesn't work, nor am I sure it's the best way. How can I have the option to navigate straight from the main app router to the student-profile screen if I include an id param?
I gave up on using named routes with child routers. If someone else understands them better than me, I'd be curious. However, I have found it works perfectly to just use the URL routing from any part of the app.
this.router.navigate('#/students/profile/' + record.id);
You don't need to use active in your child route. Aurelia router will go automatically to your child route.
export class Students {
configureRouter(config, router) {
config.map([
{ route: ['', 'home'], name: 'student-home', moduleId: 'students/students-home' },
{ route: 'list', name: 'student-list', moduleId: 'students/student-list' },
{ route: 'profile/:id', name: 'student-profile', moduleId: 'students/profile/overview' },
{ route: 'lockers', name: 'student-lockers', moduleId: 'students/lockers/home' }
]);
this.router = router;
}
}
Remove active and in your module "students/profile/overview"
call active(params) to get student from api or what ever you want you can do here with provied params.
We have sample app with router configuration defined as follows. "id" parameter in the user details route can have # in its value, such as /users/#abc. We can navigate to the user details view from users view whose "id" is #abc with no problem. However, when refreshing the details page, it goes back to the users view. Is there a way to escape character "#"?
export class App {
configureRouter(config, router) {
this.router = router;
config.title = 'Aurelia';
config.map([
{ route: ['', 'home'], name: 'home', moduleId: 'home/index' },
{ route: 'users', name: 'users', moduleId: 'users/index', nav: true },
{ route: 'users/:id', name: 'userDetail', moduleId: 'users/detail' }
]);
}
}
Since template parameters are not being encoded/decoded, they are very restrictive. Basically, this means [a-zA-Z0-9_]. Note, that this is not from documentation, but my observation.
If you need to pass any arbitrary data, just use query parameters. To do that, set up router without defining template parameter.
export class App {
configureRouter(config, router) {
this.router = router;
config.title = 'Aurelia';
config.map([
{ route: ['', 'home'], name: 'home', moduleId: 'home/index' },
{ route: 'users', name: 'users', moduleId: 'users/index', nav: true },
{ route: 'user', name: 'userDetail', moduleId: 'users/detail' }
]);
}
}
You don't have to change anything else (navigation, parameters in activate, etc.) In this way, upon navigation, it'll be turned into query parameter:
router.navigateToRoute('userDetail', { id: '#user123' });
This will result in url: http://myserver/#user?id=%23user123.
Why the Aurelia route doesn't work when we type it directly on the browser? I have configured the Aurelia to remove the "#" from the URL. It works well when clicking on the links in the website, but when I try to type the URL directly on the browser, it only works with "#".
That's the situation:
With website links
localhost/#/route -> works
localhost/route -> works
Typing on the browser
localhost/#/route -> works
localhost/route -> doesn't work
That's my configuration:
configureRouter(config, router){
config.title = 'Dreampper';
router.baseUrl = "/";
config.options.pushState = true;
var navStrat = (instruction) => {
instruction.config.moduleId = instruction.fragment
instruction.config.href = instruction.fragment
}
config.map([
{ route: 'login', moduleId: './components/account/login', name: 'login', nav: true},
{ route: 'register', moduleId: './components/account/register', name: 'register'},
{ route: '', moduleId: './components/timeline/timeline', name: 'timeline', title: 'Timeline' },
{ route: 'welcome', moduleId: './components/account/welcome', name: 'welcome' },
{ route: ':username', moduleId: './components/profile/profile', name: 'profile', nav: false }
]);
this.router = router;
}
I have the <base href="/"> on the index.html.
Someone could help me?
PushState navigation requires server-side configuration. You must configure your server appropriately. See the second yellow box at http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/cheat-sheet/7
I'm no Aurelia master and much more of a beginner.
So far i got no solution for my problem, but i think there must exist an hopefully easy way to do the following:
I got a very basic structure with the app.js and some components (e.g. admin.js ...).
Because i would like to have a navigation for the routes of all components, i need to get those routes into my app.js.
Simple, or stupid question: How do i achieve this?
I tried to simply inject the components, but i have no acces to the router attribute, no matter what i do.
Example admin component router:
configureRouter(config, router) {
config.map([
{ route: '', name: 'default', moduleId: 'components/admin/default/default' },
{ route: 'roles', name: 'roles', moduleId: 'components/admin/roles/roles', title: 'Rollenverwaltung' },
{ route: 'users', name: 'users', moduleId: 'components/admin/users/users', title: 'Nutzerverwaltung' },
{ route: 'employees', name: 'employees', moduleId: 'components/admin/employees/employees', title: 'Mitarbeiterverwaltung' }
]);
this.router = router;
}
What i tried in my app component
static inject() { return [AuthService, Admin]; }
constructor(authService, admin) {
this.auth = authService;
this.adminRouter = admin;
}
I am aware that as long i did not load the component, the router of the admin would be empty anyway. But even if the component is loaded, the router object is undefined.
A not running Gist to better show what i want (hopefully)
Maybe i am getting something basicly wrong here and don't understand the way aurelia or even js works?
Thank you for your help.
You cannot get access to the router if the Admin component itself was not composed, and even then the parent would not "inherit" the routes from admin.
If you wanted to define routes around your application and then pull them in to one place perhaps something like this would be useful for you -
parent.js
import {Admin} from './admin';
export class Parent {
static inject = [Admin];
constructor(admin) {
this.admin = admin;
this.admin.routes.forEach(route => {
this.router.addRoute(route);
}
}
}
admin.js
export class Parent {
routes = [
{ route: '', name: 'default', moduleId: 'components/admin/default/default' },
{ route: 'roles', name: 'roles', moduleId: 'components/admin/roles/roles', title: 'Rollenverwaltung' },
{ route: 'users', name: 'users', moduleId: 'components/admin/users/users', title: 'Nutzerverwaltung' },
{ route: 'employees', name: 'employees', moduleId: 'components/admin/employees/employees', title: 'Mitarbeiterverwaltung' }
];
}
Below are my views:
1. app - standard
2. home - Has a list of items on left, on selection of any, will display some content on the right side in router-view (contract-view to be loaded).
3. contract-view
app.ts: route Config:
configureRouter(config: RouterConfiguration, router: Router) {
config.title = 'Contracts Portal';
config.map([
{ route: ['', 'home'], name: 'home', moduleId: 'home', nav: true, title: 'Home' },
{ route: 'resources', name: 'resources', moduleId: 'resources', nav: true, title: 'Resources' },
{ route: 'tools', name: 'tools', moduleId: 'tools', nav: true, title: 'Tools' }
]);
this.router = router;
}
Home.ts Router Config:
configureRouter(config: RouterConfiguration, router: Router) {
config.title = "test";
config.map([
{ route: ['', 'contract-view/:id'], name: 'contract-view', moduleId: 'contract-view', nav: true, title: 'Test' }
]);
this.router = router;
}
on selection of a item in home page list, I am trying to navigate as below to load content in the right pane's router-view, in home.ts:
this.router.navigateToRoute("contract-view", { id: 4090 });
However it throws the error: Route not found: /contract-view/4090
At this point, it's still home page and default route, hence the url reads: http://localhost:9000/#/
and so it fails.
But, if I manually change the url to http://localhost:9000/#/home and then select a list item, navigation to contract-view works.
What I am I missing here?
I am looking for absolute path navigation. Tried navigating to home/contract-view but fails with error:
A route with name 'home/contract-view' could not be found. Check that name: home/contract-view was specified in the route's config.
The default route of Home.ts has a parameter:
config.map([
{ route: ['', 'contract-view/:id'], name: 'contract-view', moduleId: 'contract-view', nav: true, title: 'Test' }
]);
This might be a problem because the parameter :id is not referenced in the first name. So, I suggest you change the route as follow:
config.map([
//create another route with no parameters,
//this route will represent an empty selection of contract
{ route: [ '', 'contract-view' ], name: 'contract-view-empty', moduleId: 'contract-view-empty', Title: 'Select a Contract' }
{ route: 'contract-view/:id', name: 'contract-view', moduleId: 'contract-view', nav: true, title: 'Test' }
]);
Then, to generate a navigation link you can use route-href attr. Like this:
<a route-href="route: contract-view; params.bind: { id: 4090 }">Navigate</a>
Hope it helps!
It is an issue with Aurelia Router framework. Discussion and workaround here:
https://github.com/aurelia/skeleton-navigation/issues/230