How can I use tabs and pages in one application? - javascript

Is it possible to use tabs with pages?
I made an example. It has the following structure:
main (page)
tabs (use as a container)
---> app-routing.module.ts (routing for tabs)
---> home (tab)
---> contacts (tab)
---> details (tab)
---> about (tab)
If I use tabs as the default route, everything works(in app-routing.module.ts).
const routes: Routes = [
// { path: '', loadChildren: './main/main.module#MainPageModule' },
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' },
];
If I use the default route for the main page, then an error will appear when switching to tabs(in app-routing.module.ts).
const routes: Routes = [
{ path: '', loadChildren: './main/main.module#MainPageModule' },
{ path: 'tabs', loadChildren: './tabs/tabs.module#TabsPageModule' },
];
core.js:9110 ERROR Error: Uncaught (in promise): Error: Cannot match
any routes. URL Segment: 'tabs/home' Error: Cannot match any routes.
URL Segment: 'tabs/home'
How can I use tabs and pages in one application?

You need to add
RouterModule.forChild([
{
path: '',
component: TabsPage
}
])
To your tabs.module.ts in the imports sections.
Otherwise the router doesn't know which page of the Tab Module to Render

Related

angular 14 default router with param

I created an angular app with the last version, i updated the base href to /popup to have the url http://localhost:4200/popup
i want, when the application opens in the url http://localhost:4200/popup, it redirects me to a 404 page, but when i add a param in the url http://localhost:4200/popup/444444444 is opens a specific page.
I tried with the below code but i have this error:
main.ts:13 Error: NG04014: Invalid configuration of route
'/:requestNumber': path cannot start with a slash
<base href="/popup" />
export const routes: Routes = [
{ path: '', redirectTo: '/:requestNumber', pathMatch: 'full' },
{
path: '/:requestNumber',
component: AppComponent,
resolve: { payment: PaymentResolverService },
},
];
I added the resolver to check if the url has a param requestNumber or not.
The question isn't clear. If I understood you right - you can't expect a route with /popup/444444 to be caught by an empty path (because it is not an empty path, because it has 44444 in it), therefore, you can't write this:
{ path: '', redirectTo: '/:requestNumber', pathMatch: 'full' }
The path configuration above picks up empty paths, i.e. /popup/, when you want it to redirect to /popup/:requestNumber, where will it get the request number from?? (remember, the path that got you here was /popup/)
You can write this though, where empty paths are redirected to a 404 page:
export const routes: Routes = [
{
path: '',
component: Some404Page,
},
{
path: ':requestNumber',
redirectTo: 'popup/:requestNumber',
pathMatch: 'full',
},
{
path: 'popup/:requestNumber',
component: AppComponent,
resolve: { payment: PaymentResolverService },
},
];
Since this is the only hit on Google, I'll just add a side-answer.
I was getting this error for apparently this route:
{
path: 'stuff/moduleA',
loadChildren: () => import('./modules/module-a/module-a.module').then(m => m.module-a)
},
Which didn't make sense since there's clearly no leading slash there. The problem was actually that this lazily loaded module contained a route that looked like this:
{
path: '/',
component: AComponent,
},
The fix was to change this path by changing it to path: ''.
So check the routes inside of the loaded module, even if that route isn't mentioned in the error.

Angular - Adding custom route at the end of all routes

I want to have dynamic routing in my angular app. All my modules are lazy loaded. I resolved this problem with adding my route as child for all routes, but is little tricky. Maybe is the best way to do it, more Angular way.
Angular 7.2.0
const routes: Routes = [
{
path: '',
loadChildren: './dashboard/dashboard.module#DashboardModule'
}, {
path: 'event',
loadChildren: './event/event.module#EventModule'
}, {
path: 'account',
loadChildren: './account/account.module#AccountModule'
}, {
path: 'settings',
loadChildren: './settings/settings.module#SettingsModule'
}
];
My goal is to have route, for example: '/create' which I could add at the end of all routes.
/create
/event/create
/account/main/create

Angular : Lazy load multiple Modules with the same route

I have an app where i want to lazy load two modules in the same moment with the same route path.
My routing module would look like this :
{
path: 'mypath',
loadChildren: () => HomeModule,
canLoad: [HomeGuard]
},
{
path: 'mypath',
loadChildren: () => AdvisorModule,
canLoad: [AdvisorGuard]
},
but this lead to load only the first one
i cant' find anyway to do it like this for example :
{
path: 'mypath',
loadChildren: () => HomeModule, advisor module // ??
canLoad: [// ??]
},
I don't want also to import one of them in the other , as like this , only one module would be lazy loaded and the other automatically
How may it do it ??
You could rework things like this:
const routes: Routes = [
{
path: 'mypath/home',
loadChildren: () => HomeModule,
canLoad: [HomeGuard]
},
{
path: 'mypath/advisor',
loadChildren: () => AdvisorModule,
canLoad: [AdvisorGuard]
},
]
In other words move the route path to your module outside to the parent module, in this case I assume those are 'adviser' and 'home'
And then just start in the module routing with a redirect solution and/or a path like so:
Home module routing:
const routes: Routes = [
{
path: '', // <-- in your current solution probably 'home'
component: HomeParentComponent,
children: [
{ path: '', redirectTo: 'childOne', pathMatch: 'full' },
{ path: 'childOne', component: HomeChildComponentOne },
],
},
];
Advisor module routing:
const routes: Routes = [
{
path: '', // <-- in your current solution probably 'advisor'
component: AdvisorParentComponent,
children: [
{ path: '', redirectTo: 'childOne', pathMatch: 'full' },
{ path: 'childOne', component: AdvisorChildComponentOne },
],
},
];
This works nicely, you should be able to navigate to:
'/mypath/home' and end up inside your HomeParentComponent with router outlet of HomeChildComponent one.
'/mypath/advisor' and end up inside your AdvisorParentComponent with router outlet of AdvisorChildComponent one.
In case you don't want a child component inside your router outlet it is even simpler, you can just remove the child routes and redirect.
Note: If this solution doesn't resolve your issue, then please share more details on your module routing so I can get a better picture of your desired route configuration.
You need to re-arrange your routes by one level and you also need to add auxiliary routes for the extra components you want to load.
This works with Angular 9 (probably with 8 too)
{
path: 'home',
component: HostingComponentWithOutlets,
children: [
{
path: 'featureOne',
loadChildren: () => import('xxxxx').then(m => m.FeatureOneModule),
canLoad: [featureOneGuard]
},
{
path: 'featureTwo',
outlet: 'outletAux1',
loadChildren: () => import('yyyyy').then(m => m.FeatureTwoModule),
canLoad: [featureTwoGuard]
},
// you can even load more components to different outlets from the same module
// and update redirectTo and routerLink accordingly
//{
// path: 'featureThree',
// outlet: 'outletAux2',
// loadChildren: () => import('yyyyy').then(m => m.featureTwoModule),
// canLoad: [featureTwoGuard]
//},
{
path: '',
redirectTo:
'/absolute/path/to/home(featureOne/path-to-featureOne-component//outletAux1:featureTwo/path-to-featureTwo-component)',
pathMatch: 'full'
}
]
},
{ path: '', redirectTo: 'home', pathMatch: 'full' }
Hitting the 'home' route will lazy load all required modules.
In your HostingComponentWithOutlets html template where you need to link to 'featureOne':
<a [routerLink]="featureOne/path-to-featureOne-component"
and if you want to go straight to the full route with the auxiliary routes from a template:
<a [routerLink]="['.', { outlets: { 'primary': ['featureOne', 'path-to-featureOne-component'], 'outletAux1': ['featureTwo', 'path-to-featureTwo-component'] } }]"
FeatureOneModule should define 'path-to-featureOne-component' and FeatureTwoModule should define 'path-to-featureTwo-component' in their equivalent route definitions.

Angular 4 redirects to root path when browser reloads

The page is currently http://localhost:4200/foo.
Case 1: If I press the browser's reload button or type the same url in the browser, the page redirects to http://localhost:4200 (root path).
I'd like the page keeps in the same url (http://localhost:4200/foo).
Case 2: If I type http://localhost:4200/foo (same url) the page redirects to http://localhost:4200 (root path).
I also would like the page keeps in the same url I've typed (http://localhost:4200/foo).
Otherwise, if the page is http://localhost:4200 and I type http://localhost:4200/foo, it works fine. I can navigate by url paths normally. The problem is only when I go to the same path.
My root path in app.module.ts is:
const rootRouting: ModuleWithProviders = RouterModule.forRoot([
{
path: 'foo',
loadChildren: './foo/foo.module#FooModule'
},
{
path: '',
loadChildren: './bar/bar.module#BarModule'
},
], { });
And my path in foo.module.ts is:
const fooRouting: ModuleWithProviders = RouterModule.forChild([
{
path: 'foo',
component: FooComponent
}
]);
OBS: This question Angular 5 - redirect page to homepage on browser refresh wants exactly the opposite of mine. Now, I don't know what is the Angular default behavior for this cases.
Edit after DiPix's correction:
My root path in app.module.ts is:
const rootRouting: ModuleWithProviders = RouterModule.forRoot([
{
path: 'foo',
loadChildren: './foo/foo.module#FooModule'
},
{
path: '',
loadChildren: './bar/bar.module#BarModule'
},
], { });
And my path in foo.module.ts is:
const fooRouting: ModuleWithProviders = RouterModule.forChild([
{
path: '',
pathMatch: 'full',
component: FooComponent
}
]);
Edit 2:
Debugging with google chrome, I've set "Preserve log".
Testing with any other site, if you are at "www.anydomain.com/path" and you reload the browser, chrome writes "Navigated to 'www.anydomain.com/path'.
Testing with my app, if I am at "http://localhost:4200/foo" and I reload the browser, chrome writes "Navigated to 'http://localhost:4200/'.
The browser navigates to root path!
You need to define some routes at the root of your application. Something like this:
const routes: Routes = [
{ path: 'foo', component: FooComponent},
{ path: '', redirectTo: '/foo', pathMatch: 'full' },
{ path: '**', component: FooComponent }
];
These routes would go where you defined your forRoot() method which from you code looks like:
const rootRouting: ModuleWithProviders = RouterModule.forRoot(routes);
You've got path 'foo' in foo.module.ts what is suspicious. As you have already declared this path in app.module.ts. The point is that if you are using lazy loading then you shouldn't import foo.module in app.module. Check your import in app.module. I bet you've import this module. And don't forget to change path to '' in foo.module.ts

Angular - How can I activate AUX route with lazy loaded module?

I have an angular app which is loading lazily module.
At first the app is navigating to home where it loads the module ( named module1) :
main routing :
const routes: Routes = [
{ path: "", redirectTo: "/home", pathMatch: "full" },
{ path: "home", loadChildren: "./module1/module1.module#Module1Module" },
];
At module1 - there's also routing table :
const routes: Routes = [
{
path: "", component: Home1Component,
children: [
{ path: 'bird', outlet: 'under', component: Home2Component }
]
}
];
So since it's loading lazily , when the app starts - it goes to /home where there it loads the Home1Component
But Home1Component also has a button in it which suppose to set a value to the outlet route .
home1.component.html:
<input value="click to activate aux route" type="button" (click)="go()"/>
<router-outlet ></router-outlet>
<router-outlet name='under'></router-outlet> //<---- I want to activate only this
This is how I try to activate the outlet route :
public go() {
this.router.navigate([{ outlets: { under: ['bird'] } }], { relativeTo: this.route })
}
But I get an error :
Error: Cannot match any routes. URL Segment: 'home'
Question :
Why am I getting this error and how can I fix it ?
Online code here : Stackblitz
Well with the help of #jmw5598 who referenced me to the problem/bug with the router .
There is a problem with default empty location for lazy loaded modules.
Here is a working solution for the problem .
The key thing to understand is that lazy modules should not have empty root path
Related specific description :

Categories