Aurelia Child Router redirect to specific route - aurelia

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.

Related

# in paramertized route breaks Aurelia routes

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.

Child route doesn't work with empty route path

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.

Getting routes of a child component in aurelia

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' }
];
}

A default parent router with child routers

Consider the following two classes:
import { Router, RouterConfiguration } from 'aurelia-router';
export class MainPage
{
router: Router;
configureRouter(config: RouterConfiguration, router: Router)
{
config.map([
{ route: ['', 'entities'], name: 'entities', moduleId: './entities/entities', nav: true, title: 'Entities' },
{ route: 'structures', name: 'structures', moduleId: './structures/structures', nav: true, title: 'Data Structures' },
]);
this.router = router;
}
}
And
import { Router, RouterConfiguration } from 'aurelia-router';
export class Entities
{
private router: Router;
configureRouter(config: RouterConfiguration, router: Router)
{
config.map([
{ route: '', name: 'entities-list', moduleId: './list', nav: true, title: 'Entities' },
{ route: 'events', name: 'entity-events', moduleId: './events', nav: true, title: 'Events' },
]);
this.router = router;
}
}
The problem is that; in a page where the URL reads: http://localhost/ when I execute:
this.router.navigateToRoute('entity-events');
I get the error ERROR [app-router] Error: Route not found: events. But if I change the MainPage class to this:
import { Router, RouterConfiguration } from 'aurelia-router';
export class MainPage
{
router: Router;
configureRouter(config: RouterConfiguration, router: Router)
{
config.map([
{ route: 'entities', name: 'entities', moduleId: './entities/entities', nav: true, title: 'Entities' },
{ route: 'structures', name: 'structures', moduleId: './structures/structures', nav: true, title: 'Data Structures' },
]);
this.router = router;
}
}
In a page that URL reads http://localhost/entities, I can successfully execute the given navigateToRoute command. But then I'll lose the root route!
So how can I have a parent router with a default route and some child routes under the default route?
How about using a redirect route to redirect the default route to entities? I'm on mobile right no, so no code sample, but the docs should explain it.

Aurelia: Child Router Navigation: Route not found

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