ionic 5 - routing to details page with page id issue - ionic-framework

guys , I am creating and ionic app which has details page with page id, I am trying to configure router, its not redirecting its always on main page , my code is below please check ?
parent page route
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { RecepiesPage } from './recepies.page';
const routes: Routes = [
{
path: '',
component: RecepiesPage
},
{
path: 'recipedatail',
loadChildren: () => import('./recipedatail/recipedatail.module').then( m => m.RecipedatailPageModule)
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class RecepiesPageRoutingModule {}
details page routing
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { RecipedatailPage } from './recipedatail.page';
const routes: Routes = [
{
path: '',
component: RecipedatailPage
},
{
path: ':recipeId',
loadChildren: () => import('./recipedatail.module').then( m => m.RecipedatailPageModule)
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class RecipedatailPageRoutingModule {}

Check the angular documentation for correct router implementation

Related

How to do a lazy loaded ionic framework app with a login page

I have an app that is working great, but I want to move it behind a login page. The various modules are lazy-loaded and have been working great. However, when I change the app to always go to the login page first (where I will check login status and redirect to the app if logged in), I get an error about routes.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { PreloadAllModules, RouterModule, Routes } from '#angular/router';
const routes: Routes = [
{ path: '', loadChildren: './login/login.module#LoginPageModule' }
// this next line was how the app routed before I tried adding the login page
// { path: '', loadChildren: './tabs/tabs.module#TabsPageModule' }
];
#NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
login.router.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LoginPage } from './login.page';
const routes: Routes = [
{ path: '', component: LoginPage },
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class LoginRoutingModule { }
login.page.ts
import { ChangeDetectionStrategy, Component } from '#angular/core';
import { Router } from '#angular/router';
import { Store } from '#ngrx/store';
import { AppState } from '../_store/store/app.store';
import { filter } from 'rxjs/operators';
#Component({
selector: 'app-login',
templateUrl: 'login.page.html',
styleUrls: ['login.page.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoginPage {
constructor(private router: Router, private store: Store<AppState>) {
this.userSubscription = this.store.select(state => state.users.user).pipe(
filter(user => !!user)
).subscribe(user => {
if (user) {
// THIS IS WHERE THE ERROR HAPPENS
this.router.navigate(['/tabs']);
}
});
}
}
this.router.navigate(['/tabs']); is where the error happens:
ERROR Error: Uncaught (in promise): Error: Cannot match any routes.
URL Segment: 'tabs/behaviors' Error: Cannot match any routes. URL
Segment: 'tabs/behaviors'
I'm sure I'm missing something really obvious here. First attempt at lazy loading all the modules. I'm pretty certain I need to reference the tabs module in the login.page file somehow, or in the login.router.module. Any help would be greatly appreciated. The state check for user status works great, I've verified that all of that is working, it is just where it attempts to navigate if user is found.
Try to change to
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', loadChildren: './login/login.module#LoginPageModule' }
{ path: 'tabs', loadChildren: './tabs/tabs.module#TabsPageModule' }
];
With this code this.router.navigate(['/tabs']); you are routing to tabs, but you don't have it declare it. This is for the app.routing.ts file. Don't understand why you have the login.router.ts file.
So after following a suggestion above, and that giving me the same error, and finding no help in the docs for either angular or ionic, I went on a multi-hour change every combination of routings I could and finally something worked.
These are the routes in the app-routing.module.ts
{ path: 'login', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'tabs', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: '', redirectTo: 'login', pathMatch: 'full' },
This is the tabs.router.module.ts before the change that made it work:
{ path: 'tabs', component: TabsPage, children: [ .... ] },
{ path: '', redirectTo: 'tabs/behaviors', pathMatch: 'full' }
This is it now:
{ path: '', component: TabsPage, children: [ ... ] },
That's it. Finally figured it out when accidentally typing in the browser .com:8100/tabs/tabs/behaviors worked. Removing the path: 'tabs' in the tabs routing module fixed it. /tabs goes to the tabs routing, and then /behaviors is the child. My code had added a 2nd layer of /tabs in between the 1st and the /behavior.

PageNotFound route in root routes triggered after outsourcing routes to component

my routes used to work fine when they were all together, the notfound route
{ path: '**', component: PageNotFoundComponent}
was at the last place to capture any other not defined paths.
After I moved the recipe routes to its own module these are never called. Instead, the pagenotfound is called.
Everything works fine if I remove the PageNotFoundComponent route from the root routes. Any ideas regarding whats going on here?
This is the root app routing module:
import { Routes, RouterModule } from '#angular/router';
import { NgModule, OnInit } from '#angular/core';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { PageNotFoundComponent } from './errors/page-not-found/page-not-found.component';
import { AuthComponent } from './auth/auth.component';
const appRoutes: Routes = [
{ path: '', redirectTo: 'recipes', pathMatch: 'full' },
{ path: 'shopping-list', component: ShoppingListComponent },
{ path: 'auth', component: AuthComponent },
{ path: '**', component: PageNotFoundComponent}
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {
OnInit() {
console.log(appRoutes);
}
}
This is the child recipe routing module:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { RecipesComponent } from './recipes.component';
import { AuthGuard } from '../auth/auth.guard';
import { RecipeStartComponent } from './recipe-start/recipe-start.component';
import { RecipeEditComponent } from './recipe-edit/recipe-edit.component';
import { RecipeDetailComponent } from './recipe-detail/recipe-detail.component';
import { RecipesResolverService } from './recipes-resolver.service';
const routes: Routes = [
{
path: 'recipes', component: RecipesComponent, canActivate: [AuthGuard] , children: [
{ path: '', component: RecipeStartComponent },
{ path: 'new', component: RecipeEditComponent },
{
path: ':id',
component: RecipeDetailComponent,
resolve: [RecipesResolverService]
},
{
path: ':id/edit',
component: RecipeEditComponent,
resolve: [RecipesResolverService]
},
]
}
];
#NgModule({
declarations: [
],
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RecipesRoutingModule {
}
Thanks for taking the time to get this far, any idea would be appreciated.
The problem was that the wildcard route ('**') always should be at the end of your routes list because of the way it works.
It watches all the routes before it, and checks if any given URL, that the user is searching on matches those.
Since you've outsourced your recipes paths, and probably imported them into app.module, those paths get concatenated after the original path list that you have in your app-routing.module.
Therefore your paths in the recipe routing module end up being AFTER the wildcard route ('**'), so they get ignored by it. That's why searching on any URL listed in the recipe routing module will reroute the user to the wild card path, to your PageNotFoundComponent.
Great solution tho.
I solved the problem lazy loading all the routes and then adding the PageNotFound route '**' at the end, hope this helps anyone that faced the same problem:
import { Routes, RouterModule } from '#angular/router';
import { NgModule } from '#angular/core';
import { PageNotFoundComponent } from './errors/page-not-found/page-not-found.component';
// If new and :id children were inverted that would make angular take new as id
// ant that would break the app, the order of the routes is very important
// that's why the 404 PageNotFoundComponent goes the last one
const appRoutes: Routes = [
{ path: '', redirectTo: 'recipes', pathMatch: 'full' },
{ path: 'recipes', loadChildren: () => import('./recipes/recipes.module').then(m => m.RecipesModule) },
{ path: 'shopping-list', loadChildren: () => import('./shopping-list/shopping-list.module').then( m => m.ShoppingListModule) },
{ path: 'auth', loadChildren: () => import('./auth/auth.module').then( m => m.AuthModule) },
{ path: '**', component: PageNotFoundComponent }
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}

Adding new components with default layout

I have just downloaded the angular admin template. Then i add a new component:
ng g n test
When I navigate to the component, the default layout is not applied. I guess it uses the app.component layout. How do you tell the component it should use the default UI?
to add a new componet follow these steps:
create a component-name-routing.module.ts file
create a component-name.module.ts file
create a component-name.component.html file
create a component-name.component.ts file
component-name.component.ts file:
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: 'app-componentName',
templateUrl: './component-name.component.html',
})
export class NameComponent implements OnInit {}
component-name-routing.module.ts file
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { NameComponent } from "./component-name.component";
const routes: Routes = [
{
path: '',
component: NameComponent,
data: {
title: 'route title'
},
children: [
{
path: '',
redirectTo: ''
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ComponentNameRoutingModule {}
component-name.module.ts file
// Angular
import { CommonModule } from '#angular/common';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
// Theme Routing
import { ComponentNameRoutingModule } from "./component-name-routing.module";
import { ComponentNameComponent } from "./component-name.component";
#NgModule({
imports: [
ComponentNameRoutingModule,
],
declarations: [
ComponentNameComponent
]
})
export class ComponentNameModule {
constructor() {}
}
all this in a new folder in the views directory and you'll be good to go.

Navigate from Login page to Tabs in Ionic4?

I am creating an application and i want move from login Page to Tabs Page. When I try to navigate to Tabs page, its only showing Home page without Tabs.
here is my Code.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', loadChildren: './pages/login/login.module#LoginPageModule' },
{ path: 'tabs', loadChildren: './pages/tabs/tabs.module#TabsPageModule' }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
tabs.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { Routes, RouterModule } from '#angular/router';
import { IonicModule } from '#ionic/angular';
import { TabsPageRoutingModule } from './tabs.router.module';
import { TabsPage } from './tabs.page';
import { HomePageModule } from '../home/home.module';
import { ActivityPageModule } from '../activity/activity.module';
import { MygroupsPageModule } from '../mygroups/mygroups.module';
import { MessagesPageModule } from '../messages/messages.module';
import { SettingsPageModule } from '../settings/settings.module';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
TabsPageRoutingModule,
HomePageModule,
ActivityPageModule,
MygroupsPageModule,
MessagesPageModule,
SettingsPageModule
],
declarations: [TabsPage]
})
export class TabsPageModule {}
tabs.router.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { TabsPage } from './tabs.page';
import { HomePage } from '../home/home.page';
import { ActivityPage } from '../activity/activity.page';
import { MygroupsPage } from '../mygroups/mygroups.page';
import { MessagesPage } from '../messages/messages.page';
import { SettingsPage } from '../settings/settings.page';
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: '',
redirectTo: '/tabs/(home:home)',
pathMatch: 'full',
},
{
path: 'home',
outlet: 'home',
component: HomePage
},
{
path: 'activity',
outlet: 'activity',
component: ActivityPage
},
{
path: 'mygroups',
outlet: 'mygroups',
component: MygroupsPage
},
{
path: 'messages',
outlet: 'messages',
component: MessagesPage
},
{
path: 'settings',
outlet: 'settings',
component: SettingsPage
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TabsPageRoutingModule {}
From Login page, I am navigating in this way.
this.router.navigate(['tabs']);
but this is just showing a home page with no tabs. Can you guide me what should i do, even tabs are not showing in DOM, i tried to inspect them.
It is just showing Home Page as default Page.
I had the same issue, the navigation doen't work in tabs' page. To avoid the issue I did this :
this.navCtrl.navigateRoot('/home'); // I use NavCtroller instead of Router
and in app-routing.module.ts :
{ path: 'home', redirectTo: '/tabs/(home:home)' },
I hope it will work properly in the next beta.

How to hide ionic 4 Tabs just for login page

I'm working on a project with tabs in it but it should only appear after user login.
The tabs works just fine when its route in app.routing.module.ts is like this:
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' }
But when I use login like this:
{ path: '', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'home', loadChildren: './tabs/tabs.module#TabsPageModule' }
It doesnt work.
app.routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: '', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'home', loadChildren: './tabs/tabs.module#TabsPageModule' },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
tabs.routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { TabsPage } from './tabs.page';
const routes: Routes = [
{
path: 'home',
component: TabsPage,
children: [
{
path: '',
redirectTo: '/home/(MyPlaces:MyPlaces)',
pathMatch: 'full'
},
{
path: 'MyPlaces',
outlet: 'MyPlaces',
loadChildren: '../MyPlaces/MyPlaces.module#MyPlacesPageModule'
},
{
path: 'Messages',
outlet: 'Messages',
loadChildren: '../Messages/Messages.module#MessagesPageModule'
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TabsPageRoutingModule { }
Import the TabsPageModule and put it on app.module.ts to the imports: [...].
This works for me.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule, RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TabsPageModule } from './tabs/tabs.module';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, TabsPageModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
After so many attempts I found that this approach will never work like that at least for now the only way for this to work is to not use lazy loading the code will be like that:
app.routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { TabsPage } from './tabs/tabs.page'
const routes: Routes = [
{ path: '', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'home', component: TabsPage },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TabsPageModule } from './tabs/tabs.module';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
TabsPageModule
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Notice importing TabsPageModule.
tabs.routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { TabsPage } from './tabs.page';
import { MyPlacePage } from '../MyPlaces/MyPlaces.Page';
import { MessagesPage } from '../Messages/Messages.Page';
const routes: Routes = [
{
path: 'home',
component: TabsPage,
children: [
{
path: '',
redirectTo: '/home/(MyPlaces:MyPlaces)',
pathMatch: 'full'
},
{
path: 'MyPlaces',
outlet: 'MyPlaces',
component: MyPlacePage
},
{
path: 'Messages',
outlet: 'Messages',
component: MessagesPage
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TabsPageRoutingModule { }
tabs.module.ts
import { IonicModule } from '#ionic/angular';
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { TabsPageRoutingModule } from './tabs.router.module';
import { TabsPage } from './tabs.page';
import { MyPlacesPageModule } from '../MyPlaces/MyPlaces.module';
import { MessagesPageModule } from '../Messages/Messages.module';
#NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
TabsPageRoutingModule,
MyPlacesPageModule,
MessagesPageModule
],
declarations: [TabsPage]
})
export class TabsPageModule {}
Notice also that you need to work with href to link tabs page not routerLiknk.
I found a way to do this with lazy loading. In the page which contains the tabs we add a new variable which is a class and updated when the navigation changes:
<ion-tabs [class]="'url' + currentUrl">
</ion-tabs>
This class is updated in the .ts file:
import {Router,Event,NavigationEnd} from '#angular/router';
#Component({
selector: 'app-home',
templateUrl: './home.page.html',
styleUrls: ['./home.page.scss'],
})
export class HomePage implements OnInit {
public notificationCount = 0;
public currentUrl: string;
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationEnd) {
console.log('loading finished', event);
this.currentUrl = event.url.split('/').join('-')
}
});
}
In this way you can hide the tabbar using css in your global.scss
ion-tabs {
&.url-home-tournaments-main-play,
&.url-home-tournaments-main-play-score {
ion-tab-bar {
display: none;
}
}
}