Named router and nested routes in angular 6 - angular-routing

Can someone please assist in navigating to a specific route. I've been sitting with this for hours now. Here's what I have:
const routes: Routes = [
{
path: '', redirectTo: 'home', pathMatch: 'full'
},
{
path: 'home',
component: MainlayoutComponent,
canActivate: [AuthenticatedGuard],
children: [
{ path: 'listmanagement', component: ListmanagementComponent, outlet: 'main' },
{
path: 'buildings', component: BuildingslistComponent, outlet: 'main',
children: [
{ path: '', redirectTo: 'buildings', pathMatch: 'full' },
{ path: 'building', component: BuildingdetailComponent },
{ path: 'building/:code', component: BuildingdetailComponent }
]
},
{
path: 'calendarandrates', component: CalendarandratesComponent, outlet: 'main',
children: [
{ path: '', redirectTo: 'calendarandrates', pathMatch: 'full' },
{ path: 'rescalendar', component: RescalendarlistComponent },
{ path: 'roomrates', component: ResratesmainComponent },
]
},
{ path: 'users', component: UsersComponent, outlet: 'main' },
]
},
{
path: 'login',
component: LoginlayoutComponent,
children: [
{ path: '', component: LoginComponent, outlet: 'login' },
]
},
{
path: '**',
component: NotfoundComponent,
canActivate: [AuthenticatedGuard],
outlet: 'main'
}
];
Then in my app.component I only have the primary router outlet:
<router-outlet></router-outlet>
This router outlet is suppose to load only one of the two layout components, maned loginlayout.component and mainlayout.component: One for when a user is not logged in (so as not to show the side nav and other toolbar items, this layout component only has a simple logo on the top left and header in the middle), and other layout component has side nav and more items on the toolbar. All this is working fine and I'm able to log in using the first layout and load the 2nd layout. The outlet routers in the respective layout pages are:
<router-outlet name="login"></router-outlet>
<router-outlet name="main"></router-outlet>
Somehow, once in the main layout component, I can navigate to the 1st level child (buildings, for example) using something like:
this.router.navigate(['/home', { outlets: { main: ['buildings'] } }])
I cannot seem to figure out how I can navigate to the 2nd later child (for example, once in the buildings component, I want to navigate to the (single) building item by clicking an edit (with param) or add (without param) new button
I've search and I only get examples with only one level child, but not 2 levels as I have in this example. Any help would be appreciated.

I fixed my issue and just carried on with the development. Now that I'm done, I thought I should just post my fix. I changed the routes to look like this:
const routes: Routes = [
/*==================================Main Outlet==================================*/
{
path: '', redirectTo: 'home', pathMatch: 'full'
},
{
path: 'home', component: MainlayoutComponent, canActivate: [AuthGuard],
children: [
{ path: '', component: HomeComponent, outlet: 'main' },
{ path: 'listmanagement', component: ListmanagementComponent, outlet: 'main' },
{ path: 'buildings', component: BuildingslistComponent, outlet: 'main' },
{ path: 'buildings/building/:code', component: BuildingdetailComponent, outlet: 'main' },
{ path: 'buildings/building', component: BuildingdetailComponent, outlet: 'main' },
{ path: 'buildings/allbedspaces', component: BedspacelistComponent, outlet: 'main' },
{ path: 'calendarandrates', component: CalendarandratesComponent, outlet: 'main' },
{ path: 'calendarandrates/rescalendar', component: RescalendarlistComponent, outlet: 'main' },
{ path: 'calendarandrates/roomrates', component: ResratesmainComponent, outlet: 'main' },
{ path: 'users', component: UsersComponent, outlet: 'main' },
{ path: 'users/myaccount', component: MyaccountComponent, outlet: 'main' },
{ path: '**', component: NotfoundComponent, canActivate: [AuthGuard], outlet: 'main' }
]
},
/*==================================Login Outlet==================================*/
{
path: 'login', component: LoginlayoutComponent,
children: [{ path: '', component: LoginComponent, outlet: 'login' } ]
}
];
Then when navigating to a route I just use the following code:
this.router.navigate(['/home', { outlets: { main: ['buildings', 'allbedspaces'] } }], { skipLocationChange: true })
skipLocationChange: true because I skip all my location changes when routing and always keep the base url since I do not want users to navigate through the app using the address bar

Related

How to create authenticate in certain tabs

I just created a new ionic project with Starter template tabs, then i want to authenticate only in tab 3, but when I declare canActivate: [AuthGuardService] on routes tabs, I can’t access tabs 3 if auth value is false. because other tabs can be accessed without requiring authentication.
this is my code
tabs-routing.module.ts
AuthGuardService] on routes tabs, I can’t access tabs 3 if auth value is false. because other tabs can be accessed without requiring authentication.
this is my code
tabs-routing.module.ts
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'tab1',
children: [
{
path: '',
loadChildren: () =>
import('../tab1/tab1.module').then(m => m.Tab1PageModule)
}
]
},
{
path: 'tab2',
children: [
{
path: '',
loadChildren: () =>
import('../tab2/tab2.module').then(m => m.Tab2PageModule)
}
]
},
{
path: 'tab3',
canActivate: [AuthGuardService], /* <-- check auth */
children: [
{
path: '',
loadChildren: () =>
import('../tab3/tab3.module').then(m => m.Tab3PageModule)
}
]
},
{
path: 'tab4',
children: [
{
path: '',
loadChildren: () =>
import('../tab4/tab4.module').then(m => m.Tab4PageModule)
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
];
auth-guard.service.ts
export class AuthGuardService implements CanActivate{
constructor(
private authService: AuthenticationService,
) { }
canActivate(): boolean{
return this.authService.isAuthenticated();
}
}

how I can redirect user with angular routing

When I trying go to myaddress/home I get the error. When a user enter in address line myaddress/home need to redirect him to myaddress/home/allQuestions. Another routes work. I use angular 8.
const routes: Routes = [
{
path: '', component: MainLayoutComponent, children: [
{path: '', redirectTo: '/login', pathMatch: 'full'},
{path: 'login', component: LoginFormComponent},
{path: 'registration', component: RegistrationFormComponent}
]
},
{ path: 'home', component: HomeLayoutComponent, children: [
{path: '', redirectTo: '/allQuestions', pathMatch: 'full'},
{path: 'allQuestions', component: AllQuestionsComponent},
{path: 'addQuestion', component: AddQuestionComponent},
], canActivate: [AuthenticationGuard]
}
];
Error:
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'allQuestions'
Error: Cannot match any routes. URL Segment: 'allQuestions'
Right now with your code , angular router , will try to replace the hole route address (/home) with /login.
To set address to redirectTo, You can not use /
change the second line
...
{ path: 'home', component: HomeLayoutComponent, children: [
{path: '', redirectTo: '/allQuestions', pathMatch: 'full'},
...
to this
{path: '', redirectTo: 'allQuestions', pathMatch: 'full'},
Bug fixed code
const routes: Routes = [
{
path: '', component: MainLayoutComponent, children: [
{path: '', redirectTo: 'login', pathMatch: 'full'},
{path: 'login', component: LoginFormComponent},
{path: 'registration', component: RegistrationFormComponent}
]
},
{ path: 'home', component: HomeLayoutComponent, children: [
{path: '', redirectTo: 'allQuestions', pathMatch: 'full'},
{path: 'allQuestions', component: AllQuestionsComponent},
{path: 'addQuestion', component: AddQuestionComponent},
], canActivate: [AuthenticationGuard]
}
];
Next Step
After you fixed this code , make sure change the way you load your components and consider about using lazy loading.
What i mean is , for example for authorization purposes you can have AuthModule, that module can have his own auth-router.module.ts, that contain route information for auth module (like /signin and /signup ). This way modules will load only if the route that goes there called !

How to trigger ionViewWillLeave in Ionic 4 with route in tabs.router.module

Lifecycle hooks ionViewWillLeave / ionViewDidLeave are not triggered when placing all pages routes in TabsPageRoutingModule.
We changed the routes from app-routing.module.ts to tabs.router.module.ts to get full view of the tabbar in the Ionic 4 app. The routes works perfectly.
When the routes were in app-routing.module.ts, the ionViewWillLeave was always triggered when leaving the page (and closing the present Observables). Now the ionViewWillLeave is not triggered when leaving the page.
Route in tabs.router.module.ts
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: '',
redirectTo: '/tabs/(home:home)',
pathMatch: 'full',
},
{
path: 'home',
outlet: 'home',
component: HomePage
},
{
path: 'chats',
outlet: 'chats',
component: ChatsPage
},
...
Logging failed for ionViewWillLeave in TS file
ionViewWillEnter() {
console.log('ionViewWillEnter'); // <- In console when entering
}
ionViewWillLeave() {
console.log('ionViewWillLeave'); // <- Not in console when leaving
}
Can't figure out why the ionViewWillLeave is not printed anymore. Any help is appreciated.
Route in app-routing.module.ts
const routes: Routes = [
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: 'chats', loadChildren: './chats.module#ChatsPageModule' },
...
Logging success for ionViewWillLeave in TS file
ionViewWillEnter() {
console.log('ionViewWillEnter'); // <- In console when entering
}
ionViewWillLeave() {
console.log('ionViewWillLeave'); // <- In console when leaving
}
Solution for our problem
Breaking changes to tabs
4.0.0-beta.18 (2018-12-13)
Stopped using outlet/component in tab-router, now we directly place children pages in the tabbed path.
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'home',
children: [
{
path: '',
loadChildren: '../home/home.module#HomePageModule'
},
{
path: 'chats'
children: [
{
path: '',
loadChildren: '../chats/chats.module#ChatsPageModule'
}
]
},
...

Ionic 4 how to navigate from tab page to non-tab page keeping tab?

In Ionic 4, I have an application with a tabs ( 5 pages Home, Search, Map, Info, Tarif)
From Search page i navigate to Detail page but i want to keeping the tab menu on Detail page.
I don't know if is possible ?
How do you configure the route ?
This is my:
app-routing.module.ts
`const routes: Routes = [
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: 'map', loadChildren: './map/map.module#MapPageModule' },
{ path: 'search', loadChildren: './search/search.module#SearchPageModule' },
{ path: 'station', loadChildren: './station/station.module#StationPageModule' },
{ path: 'info', loadChildren: './info/info.module#InfoPageModule' },
{ path: 'tarif', loadChildren: './tarif/tarif.module#TarifPageModule' }
];`
and my `tabs.router.module.ts`
`const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'home',
outlet: 'home',
component: HomePage
},
{
path: 'search',
outlet: 'search',
component: SearchPage
},
{
path: 'map',
outlet: 'map',
component: MapPage
},
{
path: 'info',
outlet: 'info',
component: InfoPage
},
{
path: 'tarif',
outlet: 'tarif',
component: TarifPage
}
]
},
{
path: '',
redirectTo: '/tabs/(home:home)',
pathMatch: 'full'
}
];`
The station page must be a child page of Search page ?
You do that using this setting in app.module.ts file.
IonicModule.forRoot(MyApp, {
tabsHideOnSubPages: false
})
As ionic tabs template have this provisioning to push any detail page with in the same tab navigation stack.
So you can do it like below to push your Detail view in same Search tab section.
this.navCtrl.push(DetailPage, { detailId: detailData.id });
by doing this you can push your detail page into same Tab page.
Hope this will helps!
You have to make the Detail page a child of the "tabs" routes. This works without displaying an icon for that page in the tab icon bar.
Add an entry into the "children" array in tabs.router.module.ts:
{
path: 'detail',
children: [
{
path: '',
loadChildren: '../detail/detail.module#DetailPageModule'
}
]
},
Then you may navigate to /tabs/detail, for example in a ion-button or similar by [routerLink]="['/tabs/detail']".
If you like, you may also define a redirect route in your app-routing.module.ts:
{ path: 'detail', redirectTo: '/tabs/detail' }
A drawback of this solution is, that the tab bar icon of your "Search" page will not be coloured when the "Detail" page is displayed. But this may be solved by additional CSS formatting.

Ionic 4 Tabs not rendering completely

I'm having this weird problem, I have started a new app with Tabs and angular routing.
I have added a new Login page, and after login, the user is redirected to the tabs page.
The problem is that after the redirect, sometimes only one tab is rendered, and sometimes two tabs are rendered.
If I refresh the page or go directly to it, all 3 tabs are shown.
If I start the app on the Tabs page, again, all 3 tabs are shown.
AppRoutingModule:
const routes: Routes = [
{path: 'login', loadChildren: './login/login.module#LoginPageModule'},
{path: 'home', loadChildren: './tabs/tabs.module#TabsPageModule'},
{path: '', redirectTo: '/login', pathMatch: 'full'}];
TabsPageRoutingModule:
const routes: Routes = [
{
path: '',
component: TabsPage,
children: [
{
path: 'home',
outlet: 'home',
component: HomePage
},
{
path: 'about',
outlet: 'about',
component: AboutPage
},
{
path: 'contact',
outlet: 'contact',
component: ContactPage
}
]
},
{
path: '',
redirectTo: '/tabs/(home:home)',
pathMatch: 'full'
}];
LoginPage:
export class LoginPage implements OnInit {
responseData: any;
userData = {'email': '', 'password': ''};
constructor(public navCtrl: NavController, public apiService: ApiService, public toastCtrl: ToastController) {
}
login() {
this.apiService.login(this.userData).then((result) => {
this.responseData = result;
if (this.responseData.token) {
console.log(this.responseData);
localStorage.setItem('token', this.responseData.token);
this.navCtrl.goRoot('/home');
} else {
console.log('User already exists');
}
}, (err) => {
// Error log
console.log(err);
});
}
ngOnInit() {
}}
Any Ideas? Thanks!
As of today, November 1, 2018 the tabs in Ionic 4 (4.0.0-beta.15) have been completely changed.
https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md#400-beta15-2018-11-01
Basically, they've updated the tabs to be a tab-bar of buttons that can be used to load ion-router-outlet, ion-content or ion-nav components.
Some other benefits of this refactor include:
Can now be written as a standalone Tab Bar (with no attached Tab)
Works with a navigation component or a plain content element
Works with shadow DOM and allows easy customization of the Tab Bar
Gives full control over the elements inside of the Tab Bar
Integrates nicely with other frameworks that have different ways of rendering element nodes
Try changing
this.navCtrl.goRoot('/home');
to
this.navCtrl.goRoot('/tabs'); to
step 1:
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'home',
outlet: 'home',
component: HomePage
},
{
path: 'about',
outlet: 'about',
component: AboutPage
},
{
path: 'contact',
outlet: 'contact',
component: ContactPage
}
]
},
{
path: '',
redirectTo: '/home/tabs/(home:home)',
pathMatch: 'full'
}];
step 2:
this.navCtrl.goRoot('/home');
I had the same problem.
After reviewing my HTML I realized that I had a problem, in the "ion-tab" the input "label" its empty and this caused the problem, the error:
<ion-tab label="" icon="medkit" href="/(entidades:entidades)">
<ion-router-outlet name="entidades">
</ion-router-outlet>
</ion-tab>
the solution for me:
<ion-tab label="The label of tab" icon="medkit" href="/(entidades:entidades)">
<ion-router-outlet name="entidades">
</ion-router-outlet>
</ion-tab>
I hope it helps you