Right now I would like now how to set the name of a route in angular like Vue as I don't want to get the "path" but the alias, the same way as can be done in vue.
This is my app-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LanguagesComponent } from './languages/languages.component';
const routes : Routes = [
{path : 'login',component:LoginComponent},
{path : 'languages',component:LanguagesComponent, name:"languages.index"}, //Set the name to route as can be done in vue
{path : 'unauthorized',component:UnauthorizedComponent}
]
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Then I want to get the route name since a service in angular.
This is my sevice File:
import { LocationStrategy } from '#angular/common';
import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class PermissionByRoleService {
constructor(public router: Router,private location: LocationStrategy){}
get permissionByRole(): boolean {
if(this.getCurrentRouteName()=="languages.index"){
return true;
}
return false;
}
getCurrentRouteName(){
console.log(this.location.path() ); //Get '/languages'
console.log(this.router.url ); // I'm supposed to get '/languages' but I get '/'
console.log();// How get route name something Similar To Vue
return this.router.url ; // I neeed return route name according to porpierties of routes
}
}
Would it be possible to do this?
If so.
How can I do this?
I appreciate any help
Related
For legacy reasons I am required to handle a route where there is potential for there to be two slashes back to back because there is an optional id in the path (e.g. /base//child/2). I can not change the url in anyway (like omitting the double slashes in favor of a secondary route). Is there anyway I can get the angular router to recognize this url and either redirect it or handle it?
This minimal stackblitz example shows the problem.
It seems Angular can not parse url with double slash correctly, so the routing path mapping will not work. You can implement your own UrlSerializer instead of using the default DefaultUrlSerializer. Try to convert path "/base//child/1" to "/base/child/1".
import {UrlSerializer, UrlTree, DefaultUrlSerializer} from '#angular/router';
export class CustomUrlSerializer implements UrlSerializer {
parse(url: any): UrlTree {
let dus = new DefaultUrlSerializer();
console.log(url);
if(/\/\//.test(url)) {
url = url.replace(/\/\//, '/');
}
return dus.parse(url);
}
serialize(tree: UrlTree): any {
let dus = new DefaultUrlSerializer(),
path = dus.serialize(tree);
return path;
}
}
Register it in app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { RouterModule, UrlSerializer } from '#angular/router';
import { CatchAllComponent } from './catch-all/catch-all.component';
import { InformedComponent } from './informed/informed.component';
import { CustomUrlSerializer } from './custom-url-serializer';
#NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([{
path: 'base/child/:id',
component: InformedComponent,
}, {
path: 'base/:parentId/child/:id',
component: InformedComponent
}, {
path: '**',
component: CatchAllComponent
}])
],
declarations: [ AppComponent, CatchAllComponent, InformedComponent ],
providers: [
{ provide: UrlSerializer, useClass: CustomUrlSerializer }
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Now the url with double slash "//" will be converted to "/". It will match the routing path "base/child/:id", so you can get the params and handle it.
I'd try with UrlMatcher something along these lines
matcher.ts
import { UrlSegment } from '#angular/router';
export function matcher(url: UrlSegment[]) {
console.log(JSON.stringify(url));
return url.length === 1 && url[0].path === 'base' ? ({consumed: url}) : null;
}
routes
import { matcher } from './matcher';
RouterModule.forRoot([{
matcher: matcher,
component: InformedComponent
}, {
path: 'base/:parentId/child/:id',
component: InformedComponent
}, {
path: '**',
component: CatchAllComponent
}])
]
Tried this with your stacknblitz and it works. Not sure but other options could be listening to router's navigation started event or a route guard.
I have browsed the other similar posts on stackoverflow, but have not found one that helps my cause, so here goes:
I am using angular2 based on the webpack "boiler-plate" from angular.io and included the routing bit.
I end up with this error even though the current setup is extremely minimal:
Unhandled Promise rejection: Template parse errors:
'Mathador' is not a known element:
1. If 'Mathador' is an Angular component, then verify that it is part of this module.
...
Here are the relevant code fragments
app/app.html
<main>
<h1>Mathador prototype</h1>
<router-outlet></router-outlet>
</main>
**app/app.routes.ts**
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './pages/home/home'
const appRoutes: Routes = [
{
path: '', component: HomeComponent
}
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
**app/app.ts**
import { Component } from '#angular/core';
import '../../public/css/styles.css';
#Component({
selector : 'my-app',
templateUrl : './app.html',
styleUrls : ['./app.scss']
})
export class AppComponent {
}
**app/app.module.ts**
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { routing } from './app.routes';
// core
import { AppComponent } from './app';
// pages
import { HomeComponent } from './pages/home/home';
// components
import { Mathador } from './components/mathador/mathador';
#NgModule({
imports: [
BrowserModule,
routing
],
declarations: [
AppComponent,
HomeComponent,
Mathador
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
**app/pages/home/home.ts**
import { Component } from '#angular/core';
#Component({
selector : 'my-home',
templateUrl : './home.html',
styleUrls : ['./home.scss']
})
export class HomeComponent {
constructor() {
// Do stuff
}
}
**app/pages/home/home.html**
<h1>home!</h1>
<Mathador></Mathador>
**app/components/mathador.html**
<div>transclusion succesfull!</div>
**app/components/mathador.ts**
// Importing core components
import {Component} from '#angular/core';
#Component({
selector : 'mathador',
templateUrl : './mathador.html'
})
export class Mathador {
constructor() { }
}
I'm trying to get my head around Angular 2 (RC5) lazy-loading of modules by building a basic structure of a site with two sections, welcome and backend (think login page and main site). I've set it up following the Angular 2 docs on feature modules, one for the welcome section and one for the backend. It correctly defaults to the welcome component but my button in the welcome component that's supposed to link to the 'backend' route goes to 'welcome/backend' instead. Typing in the url with just /backend goes to /backend/welcome. Here's my app.routing.ts file:
import { Routes, RouterModule } from '#angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'welcome', pathMatch: 'full'},
{ path: 'backend', loadChildren: 'app/backend/backend.module' }
];
export const routing = RouterModule.forRoot(routes);
And my welcome.routing.ts:
import { RouterModule } from '#angular/router';
import { WelcomeComponent } from './welcome.component';
export const routing = RouterModule.forChild([
{ path: 'welcome', component: WelcomeComponent}
]);
And my welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
Anyway, here's plunk of the whole app to make it easier Plunkr. The ones that matter are in welcome and backend folders. Clicking Login should show Backend with a Logout button which takes you back to the Welcome page.
Any suggestions would be appreciated.
There were quite a few things wrong with your plunkr. Here is the working example https://plnkr.co/edit/QciaI8?p=preview
The router link was moved to app.component
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Module Test</h1>
<nav><a routerLink="../backend">Logins</a></nav>
<router-outlet></router-outlet>
`
})
export class AppComponent { }
You also need backend.routing.ts
import { Routes,
RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', redirectTo: 'backend', pathMatch: 'full'},
{ path: 'backend', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
Backend.module was changed to
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
I finally go it working by figuring out that router stacks routes from nested modules (e.g. 'backend' route in app.routing and 'backend' in backend.routing results in '/backend/backend' as the url). So the solution was to have a backend.routing.ts with a single route of { path: '', component: BackendComponent }. It was also necessary to add a / to the routerLink values (e.g. /backend instead of backend). Here's my final backend.routing.ts:
import { Routes, RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
And backend.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
backend.component.ts
import { Component } from '#angular/core';
#Component({
template: `
<h2>Backend</h2>
<nav><a routerLink="welcome">Logout</a></nav>
`
})
export class BackendComponent { }
This resulted in the login button taking me to /backend and the logout button taking me to /welcome as expected. Here's a link to the plunk: Plunker
before redirecting to page i am doing simple check using below service
import { Injectable,OnInit } from '#angular/core';
export class UserCheck {
private userState:boolean = false;
get isValid(): boolean{
return this.userState;
}
set isValid(usrstate){
this.userState = usrstate;
}
}
User check is service that set isValid to true or false in another service;
Assume that another service has set isValid to true, I am using providers to have sigle instance of UserCheck of usercheck service. But when guard actually get executed its not considering value that was set to true.
import { CanActivate,ActivatedRouteSnapshot,RouterStateSnapshot } from '#angular/router';
import { UserCheck } from './UserCheck' ;
import { Observable } from 'rxjs/Rx';
import { Injectable } from '#angular/core';
#Injectable()
export class UserDetailGuard implements CanActivate{
constructor (private usrstate:UserCheck){
console.log ("guard in action " + this.usrstate.isValid) }
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot) : Observable<boolean> | boolean{
console.log ("guard executed.. " + this.usrstate.isValid)
return this.usrstate.isValid;
}
}
As soon as page load value of this.usrstate.isValid can be seen to true in console log guard in action true in constructor code (see image), but when i actually navigate to page it does not consider value of this.usrstate.isValid and assign default value which is false.
app.module.js
Removed unnecessary code..
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { FormsModule,ReactiveFormsModule } from '#angular/forms';
import { routing } from './app.rotes';
import { UserCheck } from './UserCheck';
import { LogMessage } from './LogMessage';
import { AccessDenied } from './AccessDenied';
import { UserDetailGuard } from './UserDetailGuard'
#NgModule({
imports: [ BrowserModule,FormsModule,ReactiveFormsModule,routing,],
declarations: [ AppComponent,AccessDenied ],
bootstrap: [ AppComponent],
providers: [UserCheck,LogMessage,UserDetailGuard]
})
export class AppModule { }
I'm struggling to capture URL query string parameters being passed to my angular2 app by a 3rd party API. The URL reads http://example.com?oauth_token=123
How can I capture the value of "oauth_token" inside a component? I'm happily using the component router for basic routing it's just the query string. I have made several attempts and my latest receiving component looks like
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
template: ''
})
export class TwitterAuthorisedComponent implements OnInit {
private oauth_token:string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
console.log('the oauth token is');
console.log( this.route.snapshot.params.oauth_token );
}
}
Any advice is appreciated.
** UPDATE
If I comment out all my routes the query parameters will stick however, the moment I include a route the query parameters are removed on page load. Below is a stripped down copy of my routes file with one route
import {NavigationComponent} from "./navigation/components/navigation.component";
import {TwitterAuthorisedComponent} from "./twitter/components/twitter-authorised.component";
import { provideRouter, RouterConfig } from '#angular/router';
export const routes: RouterConfig = [
{ path: '', component: TwitterAuthorisedComponent }
];
export const appRouterProviders = [
provideRouter(routes)
];
If I remove the route the query params stick. Any advice?
I you can catch the query prams using the bellow solution.
import { Router, Route, ActivatedRoute } from '#angular/router';
queryParams:string;
constructor(private router: Router, private actRoute: ActivatedRoute)
{
this.queryParams=
this.router.routerState.snapshot.root.queryParams["oauth_token"];
}
Using this you will get the value of oauth_token to queryParams. I think this seems fine for you
If you need to update the value queryParams, query parameter changes you need to add some more code. Its like below.
import { Router, Route, ActivatedRoute } from '#angular/router';
queryParams:string;
sub:any;
constructor(private router: Router, private actRoute: ActivatedRoute)
{
this.queryParams=
this.router.routerState.snapshot.root.queryParams["oauth_token"];
}
ngOnInit(){
this.sub = this.router.routerState.root.queryParams.subscribe(params => {
this.queryParams = params["oauth_token"];
});
}
Hope it will work for you.
Query parameters can be obtained through the Router service.
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
template: ''
})
export class TwitterAuthorisedComponent implements OnInit {
private oauth_token:string;
constructor(private router: Router) {}
ngOnInit() {
console.log('the oauth token is');
console.log( this.router.routerState.snapshot.queryParams.oauth_token );
}
}
You can do this by
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
template: ''
})
export class TwitterAuthorisedComponent implements OnInit {
sub: any; //new line added
private oauth_token:string;
constructor(private router: Router) {}
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['oauth_token'];
console.log('the oauth token is');
console.log(id);
});
}
}
Hope this will help. Thank you