not able to add routes in aurelia.js - aurelia

Not able get routes even though added routes in app.js.
I am using below code to navigate to route. But getting error saying no route available.
this.router.navigateToRoute(‘Summary’, { replace: true, trigger: true });
app.js code:
import { inject } from ‘aurelia-framework’;
#inject(Element)
export class App {
constructor(element) {
debugger
this.element = element;
this.Id = null;
this.message = ‘App’;
if (element)
this.Id = element.dataset[‘id’];
}
configureRouter(config, router) {
config.title = ‘App’;
config.map([
{
route: 'Summary',
name: 'Summary',
moduleId: '../src/summary-control',
nav: true
},
{
route: 'Detail',
name: 'Detail',
moduleId:'../src/detail-control',
nav: true,
title: 'Details'
},
]);
this.router = router;
}
} ```

Related

Vue Router Resets Global Data

Im trying to store user data globally using a Vue mixin: (main.js)
import Vue from 'vue';
import Resource from 'vue-resource'
import App from 'App';
import router from 'router/index';
Vue.use(Resource);
Vue.mixin({ //globals
delimiters: ["[[", "]]"],
http: {
root: 'http://127.0.0.1:5000/'
},
data: function() {
return {
user: {
authorized: false,
username: '',
password: '',
avatar: '',
entry: '',
skill: '',
arena: {
id: '',
start: false,
votes: '',
}
}
}
}
});
new Vue({
router: router,
el: '#app',
components: {
App
},
template: '<App/>'
});
I get the data from a login page just fine: (part of Login.vue)
import Vue from 'vue';
export default {
name: 'Login-Page',
data() {
return {
message: 'Hello Vue!'
}
},
methods: {
_make_basic_auth(user, pass) {
var tok = user + ':' + pass;
return "Basic " + btoa(tok);
},
_fetch_user(protocol) {
this.message = 'waiting...';
var auth = this._make_basic_auth(this.user.username, this.user.password);
Vue.http.headers.common['Authorization'] = auth;
this.$http[protocol]('api/u/' + this.user.username).then(response => {
this.message = "Success";
if (response.body.authorized) {
this.user = {...this.user, ...response.body};
setTimeout(() => {
this.$router.push({
name: 'Profile',
params: {
id: this.user.username
}
});
}, 1000);
}
}, response => {
this.message = response.body;
console.log(response.status + " " + response.body);
});
},
register() {
this._fetch_user('post');
},
login() {
this._fetch_user('get');
}
}
}
The data is just reset on redirect: (part of Main.vue)
import Profile from 'components/Profile'
export default {
name: "Main-Page",
methods: {
enterArena() {
this.$http.get('api/match').then(response => {
console.log(response.body);
this.user.arena = {...response.body, ...this.user.arena};
this.$router.push({
name: "Arena",
params: {'id': response.body.id}
});
}, error => {
console.log(error.status + " " + error.body);
});
}
},
created() {
console.log(this);
console.log(this.user);
if (!this.user.authorized)
this.$router.push({
name: "Login"
});
}
}
It was working before, here is my old repo https://github.com/Jugbot/Painter-Arena-Web-API/tree/6f3cd244ac17b54474c69bcf8339b5c9a2e28b45
I suspect that the error is from my new arrangement of components in my Router or flubbed this references.
index.js:
routes: [
{
path: '',
name: 'Main',
component: Main,
children: [
{
path: '/arena/:id',
name: 'Arena',
component: Arena
},
{
path: '/u/:id',
name: 'Profile',
component: Profile
}
]
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/404',
component: NotFound
},
{
path: '*',
redirect: '/404'
},
],
mode: 'hash'
Update:
Problem is still unsolved but as a workaround I just moved all mixin data to the $root instance and that managed to work.
I recommend you to use vuex for better state management. It is complicated to use mixins as a data storage for a vue application. Using vuex is convenient way to manipulate dynamic or static data across the application and will not be deleted in destroy hook upon exiting on a component.

aurelia redirect line gives error "ERROR [app-router] Error: Unable to find module with ID: not-found"

I have been implementing an authorization step which I modeled on THIS question's answer by fragsalat.
Everything works until it reaches the line
return new Redirect('login');
upon which I get the error:
aurelia-logging-console.js:47 ERROR [app-router] Error: Expected router pipeline to return a navigation result, but got [{"url":"login","options":{"trigger":true,"replace":true},"shouldContinueProcessing":false}] instead.
at processResult (aurelia-router.js:1761)
at aurelia-router.js:1725
at <anonymous>
I am not sure why this has not just redirected?
This is the full app.ts file so you might see the context:
import { Aurelia, PLATFORM, autoinject } from "aurelia-framework";
import {
Redirect,
NavigationInstruction,
Router,
RouterConfiguration,
Next
} from "aurelia-router";
import { AuthService } from "../../auth/auth-service";
//import { Clients } from '../../public/components/login/login'
#autoinject
export class App {
public router: Router;
private TOKEN_KEY = "session";
configureRouter(config: RouterConfiguration, router: Router): void {
this.router = router;
config.title = "Aurelia";
config.addAuthorizeStep(AuthorizeStep);
config.map([
{
route: ["", "scheduler"],
name: "scheduler",
settings: {
icon: "scheduler",
auth: true,
roles: ["Employee", "Admin"]
},
moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"),
nav: true,
title: "scheduler"
},
{
route: "clients",
name: "clients",
moduleId: PLATFORM.moduleName(
"../components/clients/clientList/clientList"
),
title: "Clients",
nav: true,
settings: {
nav: [
{ href: "#clients/clientsList", title: "Client List" },
{ href: "#clients/Create", title: "Create Client" }
],
auth: true,
roles: ["Employee", "Admin"],
pos: "left"
}
},
{
route: "clients/ClientsList",
name: "clientList",
moduleId: PLATFORM.moduleName(
"../components/clients/clientList/clientList"
),
settings: {
auth: true,
roles: ["Employee", "Admin"]
}
},
{
route: "clients/create",
name: "aboutTeam",
moduleId: PLATFORM.moduleName(
"../components/clients/clientCreate/clientCreate"
),
settings: {
auth: true,
roles: ["Employee", "Admin"]
}
},
{
route: "logout",
name: "logout",
settings: {
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "right"
},
moduleId: PLATFORM.moduleName("../components/auth/logout/logout"),
nav: true,
title: "Logout"
},
{
route: "not-found",
name: "not-found",
settings: {
auth: true,
roles: ["Employee", "Admin"]
},
moduleId: PLATFORM.moduleName("../components/notFound/notFound"),
nav: false,
title: "Not Found"
},
{
route: "login",
name: "login",
settings: {
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "right"
},
moduleId: PLATFORM.moduleName("../../public/components/login/login"),
nav: true,
title: "login"
}
]);
config.mapUnknownRoutes("not-found");
}
}
#autoinject
class AuthorizeStep {
private endDate: any;
static loginFragment = '../../public/components/login/login';
constructor(
private authService: AuthService,
private router: Router,
private aurelia: Aurelia
) { }
run(navigationInstruction: NavigationInstruction, next: Next): Promise<any> {
return Promise.resolve()
.then(() => this.checkAuthentication(navigationInstruction, next))
.then(result => result || this.checkAuthorization(navigationInstruction, next))
.then(result => result || this.checkOrigin(navigationInstruction, next))
.then(result => result || next());
}
checkAuthentication(navigationInstruction, next) {
// Do we have a JWT?
const session = this.authService.getIdentity();
if (!session) {
this.forceReturnToPublic(next); // No JWT - back to the public root.
}
console.log("CHECKaUTHENTICATION: ", navigationInstruction.getAllInstructions().some(i => i.config.settings.auth) )
if (navigationInstruction.getAllInstructions().some(i => i.config.settings.auth)) {
// Is the token valid?
if (this.authService.hasTokenExpired(session)) {
const currentUrl = navigationInstruction.fragment + (navigationInstruction.queryString ? `?${navigationInstruction.queryString}` : '');
console.log("FRAGMENT: ", navigationInstruction.fragment);
console.log("NAVIGATE INSTRUCTION: ", navigationInstruction)
console.log('currentURL: ', currentUrl);
localStorage.setItem('origin', currentUrl);
console.log("AuthorizeStep.loginFragment", AuthorizeStep.loginFragment)
next.cancel();
console.log("and it gets here!");
return new Redirect('login');
}
}
}
checkAuthorization(navigationInstruction, next) {
var usersRole = this.authService.getUserRole();
let requiredRoles = navigationInstruction.getAllInstructions()
.map(i => i.config.settings.roles)[0];
console.log("route Roles: ", requiredRoles);
let isUserPermited = requiredRoles ? requiredRoles.some(r => r === usersRole) : true;
console.log("isUserPermited: ", isUserPermited);
if (!isUserPermited) {
this.forceReturnToPublic(next);
}
}
checkOrigin(instruction, next) {
const origin = localStorage.getItem('origin');
// Check if we were not redirected to login page and have an origin
if (instruction.fragment !== AuthorizeStep.loginFragment && origin) {
localStorage.removeItem('origin');
return next.cancel(new Redirect(origin));
}
}
forceReturnToPublic(next) {
if (localStorage.getItem('origin')) {
localStorage.removeItem('origin') // Just in case we had origin set.
}
next.cancel();
this.authService.clearIdentity();
this.router.navigate("/", { replace: true, trigger: false });
this.router.reset();
this.aurelia.setRoot("public/public/public");
}
}
In all other pipeline steps you're using return next.cancel(new Redirect()), it should be the same case, as the pipeline step expects a Next as a return value, but you return a Redirect here.
Try changing it to
return next.cancel(new Redirect('login'));

Aurelia Child Router redirect to specific route

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.

Why I'm not getting the params in activate method?

Working more on my previous example, I've got three classes. First the parent:
import { Router, RouterConfiguration } from 'aurelia-router';
export class MainPage
{
router: Router;
configureRouter(config: RouterConfiguration, router: Router)
{
config.map([
{ route: '', redirect: 'entities' },
{ 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;
}
}
Then the bigger brother:
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: ':name/events', name: 'entity-events', moduleId: './events', nav: true, title: 'Events' },
]);
this.router = router;
}
}
And finally the little sister:
import { inject, computedFrom } from 'aurelia-framework';
import { Services } from './services';
#inject(Services)
export class Event
{
private events = [];
constructor(private services : Services) {}
async attached(params, routeConfig)
{
debugger;
this.events = <any> await this.services.getEvents(params.name);
}
}
And I use the following method call to navigate to the little sister:
this.router.navigateToRoute('entity-events', { name: "Some Name" });
But when I get to the debugger breakpoint, there's no params, it's undefined. According to the documentation, there supposed to be an object passed to the activate method, containing the parameters of the route. Where did go wrong?
Use the activate method.
The params argument is passed to activate, not attached as you've written above.
async activate(params, routeConfig)
{
debugger;
this.events = <any> await this.services.getEvents(params.name);
}

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.