I have a standard set of Routes:
export const ROUTES: Routes = [
{
path: '', redirectTo: 'home'
},
{
path: 'notentitled', component: 'NotEntitledComponent'
},
{
path: 'welcome', component: 'WelcomeComponent', canActivate: [RoutingService]
},
{
path: 'active', component: 'ActiveComponent', canActivate: [RoutingService]
},
{
path: 'table', component: 'TableComponent', canActivate: [RoutingService]
},
{
path: '**', component : NotFoundComponent
}
];
The canActivate method pulls in the users entitlement credentials and checks the target route ie 'active' against their entitlement ie:
public canActivate(route: ActivateRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
let target = state.url;
return entitlementService.getUserInfo()
.pipe(
map(data => {
let canSeePage = data?.entitlements?['target'];
return canSeePage;
}),
catchError((error: any) => {
route.navigate(['notentitled']);
return of(false);
});
}
I want to add some logic to cater to a scenario. If in the entitlement check ie:
let canSeePage = data?.entitlements?['target'];
false; before returning false; check if user can see any other page and redirect there.
Example, user requests 'active' route, however, this fails:
let canSeePage = data?.entitlements?['target']; // ie data.entitlements.active: false
However, data.entitlements.table is true, so redirect to 'table'
Related
My Requirement is From Backend I am getting routes as "app/dashboard?dashboard_id={id}"
How can I configure this in Module.ts file?
I tried using below
const routes: Routes = [
{
path: "app/dashboard/:dashboard_id",
component: AddEditComponent,
canActivate: [AuthGuard],
},
];
but I am getting errors like routes are not defined.
Can Someone Please Help me on that how can I configure this route as I need to catch this id as queryParams in Component.
You can do something like this:
const routes: Routes = [
{
path: "app/dashboard",
component: AddEditComponent,
canActivate: [AuthGuard],
children: [
{
path: ':dashboard_id'
component: NewComponentId
}
]
},
];
and in your NewComponentId you can do something like inside the constructor to catch the id:
this.route.paramMap.pipe(
map((paramMap) => {
if (paramMap.get('id') !== 'something') {
// your code
}
}),
Required Route param:
{path: 'users/:userId', component: UserComponent}
and get it from param:
constructor(params: RouteParams) {
var paramId = params.get("id");
}
Optional Route Param:
{ path: '/user', component: UserComponent }
its just define the route part and param pass by query string, to read the queryparam:
this.route.queryParams
.subscribe(params => {
console.log(params);
}
);
you must process the query string for this route: "app/dashboard?dashboard_id={id}"
Update:
To set the queryparam in routerlink use it this way:
<a routerLink="/dashboard" [queryParams]="{ dashboard_id: 11 }"
>another dashboard</a>
i have two routes :-
1- http://localhost:4200/members/10 ===> this for member's page
2- http://localhost:4200/members/10?tab=3 ===> this for chat page
I want to make chat as a paid service so I create component I called it charge with this route ==> http://localhost:4200/charge so if any member like to go to chat route he will be redirected to charge page as I create code in ngOnInit method in chat component like that
if(!this.authService.paid)
{this.router.navigate(['charge']);}
When I go chat it redirects me to charge page and that's cool , the problem is that when I go member'page it redirects me to charge page and that's not cool at all, so please help me what can i do to solve this problem, thanks in advance
and this is my routes
export const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{
path: '',
runGuardsAndResolvers: 'always'
, canActivate: [AuthGuard],
children: [
{
path: 'members', component: MemberListComponent, resolve: {
users: MemberListResolver
}
},
{
path: 'member/edit', component: MemberEditComponent, resolve: {
user: MemberEditResolver
}, canDeactivate: [PreventUnsavedChangesGuard]
},
{
path: 'members/:id', component: MemberDetailComponent, resolve: {
user: MemberDetailResolver
}
},
{
path: 'lists', component: ListsComponent, resolve: {
users: ListResolver
}
},
{ path: 'messages', component: MessagesComponent, resolve: { messages: MessageResolver }, canActivate: [MessagesGuard] },
{ path: 'charge', component: PaymentComponent }
]
},
{ path: '**', redirectTo: '', pathMatch: 'full' }
];
It looks like you use the same ngOnInit implementation for both pages '/member' and '/chat'. And if this !this.authService.payed returns true, you will always be redirected to '/charge' page.
But to have a better understanding, please provide your routing configuration.
Edit:
Thank you for adding your routes.
{
path: 'members/:id', component: MemberDetailComponent, resolve: {
user: MemberDetailResolver
}
}
It seems like you check for !this.authService.payed in MemberDetailComponent#ngOnInit, but you probably do not check your queryParam ?tab=3.
To fix this issue quickly you can modify your if-condition:
if(!this.authService.payed && this.route.snapshot.queryParams['tab'] === 3)
where this.route has to be injected via constructor parameter
constructor(private route: ActivatedRoute)
But
I think the best solution for this issue would be to add another child route for chat page and handle authorization with another 'canActivate'.
I am trying to create a SPA which shows dealer in every state of austria. For example if a user visits example.com/vienna it shows every dealer in vienna. But if a users visits example.com/paris, he will still get directed to the dynamic route /paris but of course there will be nothing shown.
So my approach was to check if the state which the user wants to search for is available in the list of state and therefore directing it to the available state or redirect him to a 404 page.
If the state is available it works, but if I'll try to go to a non existing state I am stuck in a loop from next('/404')
export default new Router({
routes: [{
path: '/',
name: 'Home',
component: Home
},{
path: '/:region',
component: RegionQuery,
beforeEnter: (to, from, next) => {
let isRegion = false;
let allRegions = storeConfig.state.states;
let toRegion = to.params.region;
for(var i in allRegions){
if(allRegions[i].route === toRegion){
isRegion = true;
}
}
if (isRegion) {
next();
} else {
next('/404');
}
}
},
{
path: '/404',
name: '404',
component: NotFound
},
{
path: '*',
redirect: '/404'
},
],
})
What am I doing wrong or is there a better approach to my problem?
/404 is matched to /:region
You need to change your path order
export default new Router({
routes: [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/404',
name: '404',
component: NotFound
},{
path: '/:region',
component: RegionQuery,
beforeEnter: (to, from, next) => {
let isRegion = false;
let allRegions = storeConfig.state.states;
let toRegion = to.params.region;
for(var i in allRegions){
if(allRegions[i].route === toRegion){
isRegion = true;
}
}
if (isRegion) {
next();
} else {
next('/404');
}
}
},
{
path: '*',
redirect: '/404'
},
]
I'm trying to get the redirect after login working based on the documentation from angular.
https://angular.io/docs/ts/latest/guide/router.html#!#teach-authguard-to-authenticate
I got basically the same setup albeit that some filenames are different.
The problem is that when i log the RouterStateSnapshot url in the authGuard,
it wil always output the first route from app-routing.module.ts ('/countries') instead of e.g. /countries/france/34
authGuard
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url = state.url;
console.log(state); // always outputs first route from app-routing.module.ts ('/countries')
return this.checkLogin(url);
}
checkLogin(url: string): boolean {
if (this.userService.isLoggedIn()) {
return true;
}
this.userService.redirectUrl = url;
console.log(this.userService.redirectUrl);
// not logged in so redirect to login page
this.router.navigate(['/login']);
return false;
}
App routing module
const routes: Routes = [
{ path: '', redirectTo: 'countries', pathMatch: 'full', canActivate: [AuthGuard]},
{ path: 'login', loadChildren: './authentication/authentication.module#AuthenticationModule' },
{ path: 'countries', loadChildren: './countries/countries.module#CountriesModule'},
...
];
Country routing module
const routes: Routes = [
{ path: '', component: CountriesComponent, canActivate: [AuthGuard] },
{ path: ':name/:id', component: CountryComponent, canActivate: [AuthGuard] }
];
Hope someone can help
you are using same AuthGuard for all the paths, hence you are seeing that result, you can either create different Auth guards for different routes or have some logic to identify when the same canActivate is called.
Hope this helps!!
nprogress works just fine in every other regard, but on redirect to /login it spins forever. I've attempted the showProgressBar: false to no avail.
If user is logged in they'll be redirected to /dashboard, if they are not they will be redirected to /login.
My code looks like this:
const routes = [
{path: '/', name: 'root', redirect: { name: 'login' }, meta: {showProgressBar: false}},
{path: '/login', component: LoginPage, name: 'login', beforeEnter: loggedIn, meta: {showProgressBar: false}},
{path: '/dashboard', component: DashboardPage, name: 'dashboard', meta: { requiresAuth: true }},
{path: '/editor', component: PhoneEditorPage, name: 'editor', meta: { requiresAuth: true }},
{path: '/usersettings', component: PinPasswordPage, name: 'pinpassword', meta: { requiresAuth: true }},
{path: '/callforwarding', component: CallForwardingPage, name: 'callforwarding', meta: { requiresAuth: true }},
{ name: 'dropdown', path: '/dropdown', component: Dropdown, meta: { requiresAuth: true }}
]
const router = new VueRouter({
linkActiveClass: 'active',
mode: 'hash',
routes
})
function loggedIn (to, from, next) {
const authUser = JSON.parse(window.localStorage.getItem('authUser'))
if (authUser && authUser.auth) {
next({name: 'dashboard'})
} else {
next()
}
}
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
const authUser = JSON.parse(window.localStorage.getItem('authUser'))
if (authUser && authUser.auth) {
next()
} else {
next({name: 'login'})
this.nprogress.done()
}
}
next()
Thank you for your time.
Isn't simple to answer without see code in action, but, you can try to invert call to this.nprogess.done() and next(...) like this:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
const authUser = JSON.parse(window.localStorage.getItem('authUser'))
if (authUser && authUser.auth) {
next()
} else {
this.nprogress.done(); // <- HERE
next({name: 'login'})
}
}
next()
}
since next() call move context to new component, and I'm not sure call to nprogress will be called on the right moment.