Preloading Strategy issue for forChild routes - angular7

My application is a bit large in size. It contains many feature modules and most are lazily loaded. I want to preload a lazily loaded module, which is included in forChild routes.
For this, I have referred to Angular documentation and followed their steps. I have provided a custom preloading strategy service mentioned below.
This is my custom preloading strategy file:
#Injectable()
export class CustomPreloadingWithDelayStrategy implements PreloadingStrategy {
preload(route: Route, load: () => Observable<any>): Observable<any> {
if (route.data && route.data['preload']) {
return load();
} else {
return Observable.of(null);
}
}
}
app-routing file,
const routes: Routes =
[
XXX,
{
path: '',
data: {
base: true
},
component: MyComp,
children: [
{
path: 'page1/:id',
loadChildren: 'XXXXXXX'
},
{
path: 'page2',
loadChildren: 'XXXXXXXX'
},
{
path: 'page3',
loadChildren: 'app/feature-modules/folder1/my-folder1-module#Folder1Module'
}];
#NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true, preloadingStrategy: CustomPreloadingWithDelayStrategy})],
exports: [RouterModule],
entryComponents: [ ]
})
export class AppRoutingModule {}
My Folder1Module's routing file:
const routes: Routes = [{
path: 'sub-page1/:data1/:data2',
loadChildren: 'app/feature-modules/sub-pages/pages/sub-page1.module#SubPage1Module'
}, {
path: 'sub-page2/:data1',
loadChildren: 'app/feature-modules/sub-pages/pages/sub-page2.module#SubPage2Module',
data: {preload: true}
}];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class Folder1RoutingModule {
}
So when I open this route /page3/sub-page1/data1/data2, SubPage2Module is to be preloaded. But that is not happening.

I have spent nearly 2 hours to understand why the module is not pre-loaded even when I was doing everything right.
The problem lies with children, any route that is defined and further distributed with children is considered as a normal route even if you've defined your modules within the children with the help of loadChildren. The preloadingStrategy just takes modules to preload and not path/routes. The moment you've defined your routes under children it considers it as normal route and moves on to scan other routes that are provided with loadChildren. Following is the interpretation of Angular with your routes:
const routes: Routes =
[
XXX, // Normal path
{
path: '',
data: {
base: true
},
component: MyComp,
children: [ // Normal path (no module) as children is used, move on
{
path: 'page1/:id',
loadChildren: 'XXXXXXX'
},
{
path: 'page2',
loadChildren: 'XXXXXXXX'
},
{
path: 'page3',
loadChildren: 'app/feature-modules/folder1/my-folder1-module#Folder1Module'
},
],
},
{ path: 'abc', loadChildren: '../path/to/module#AbcModule', data: { preload: true }} // Module found, preload it!
];
If you debug closely in your custom CustomPreloadingWithDelayStrategy then you will observe that your route /page3/sub-page1/data1/data2 can't even make up to the route parameter of preload() method because preloading is all about loading module and not about loading routes. However, our route abc does make an appearance! Hope it helps :)

Related

error adding app-routing.module in stackblitz

Here: https://stackblitz.com/edit/partehoras?file=src/app/app.module.ts
When I add App Roting like I do it in my VS Code local project without any problem
In package.json
I get this error: "Error in src/app/app.module.ts (5:34)
Cannot find module './app-routing.module' or its corresponding type declarations."
Any idea, please?
Thanks
You already have RouterModule.forRoot([]) imported in the app module, I am assuming you want to move to a separate file, if so, you need to create a file in the same folder as the app module with the name app-routing.module.ts and add the following code
import { RouterModule, Routes } from '#angular/router';
import { ListadoEmpleadosComponent } from './empleados/listado-empleados/listado-empleados.component';
import { NgModule } from '#angular/core';
export const routes: Routes = [
{ path: 'empleados', component: ListadoEmpleadosComponent },
{ path: '', redirectTo: 'empleados', pathMatch: 'full' },
{ path: '**', redirectTo: 'empleados', pathMatch: 'full' },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
P.S. if you generate an angular app using the angular CLI you will get a prompt to create app routing module which will create the file automatically.

Nestjs - Typeorm custom connection name

I have a Nestjs db Module and it works perfectly
#Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: () => {
return {
name: 'default', // <=== here
type: "mysql",
...
};
},
}),
TypeOrmModule.forFeature(entities, 'default'), // <=== here
],
exports: [TypeOrmModule],
})
export class DBModule {}
if I change the connection name to anything else rather then 'default' say 'test' I get an error
#Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: () => {
return {
name: 'test', // <=== here
type: "mysql",
...
};
},
}),
TypeOrmModule.forFeature(entities, 'test'), // <=== here
],
exports: [TypeOrmModule],
})
export class DBModule {}
[Nest] 10746 - 05/15/2021, 5:55:34 PM [ExceptionHandler] Nest can't resolve dependencies of the test_UserEntityRepository (?). Please make sure that the argument testConnection at index [0] is available in the TypeOrmModule context.
Potential solutions:
- If testConnection is a provider, is it part of the current TypeOrmModule?
- If testConnection is exported from a separate #Module, is that module imported within TypeOrmModule?
#Module({
imports: [ /* the Module containing testConnection */ ]
})
The error seams to only show up if I use TypeOrmModule.forRootAsync
For TypeOrmModule.forRoot if works!
Is there any different way to indicate the connection name? I need to add another connection and can't do it because of this error. Really would like to use 'forRootAsync'
Pass the connection name as follows.
#Module({
imports: [
TypeOrmModule.forRootAsync({
name: 'test', // <=== here
useFactory: () => {
return {
type: "mysql",
...
};
},
}),
TypeOrmModule.forFeature(entities, 'test'), // <=== here
],
exports: [TypeOrmModule],
})
export class DBModule {}

NativeScript IOS Safe Area issue with Children Action Bar

I uses the "#nativescript-community/ui-material-tabs" plugin to show tabs in IOS and Android.
The problem is, the component "strangely" affect the top safe area in IOS (tested in IPhone 11 Pro) as you can see below:
I have troubleshoot and determine the issue to be when using MD Tabs and Nested Routing (where the Action Bar is defined in children tab).
Below is the associated components:
app.component.html
<page-router-outlet></page-router-outlet>
app-routing.module.ts
import { NgModule } from '#angular/core'
import { Routes } from '#angular/router'
import { NativeScriptRouterModule } from '#nativescript/angular'
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{
path: 'home',
loadChildren: () => import('~/app/home/home.module').then((m) => m.HomeModule),
}
]
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule],
})
export class AppRoutingModule {}
home.component.html
<MDTabs tabsPosition="bottom">
<MDTabStrip>
<MDTabStripItem>
<Label text="Featured"></Label>
<Image src="font://" class="fas"></Image>
</MDTabStripItem>
</MDTabStrip>
<MDTabContentItem>
<page-router-outlet name="featuredTab"></page-router-outlet>
</MDTabContentItem>
</MDTabs>
home.component.ts
...
export class HomeComponent implements OnInit {
constructor(private routerExtension: RouterExtensions,
private activeRoute: ActivatedRoute, private page: Page) {
this.page.actionBarHidden = true; // as can be seen the action bar is hidden in the parent tabs component.
}
ngOnInit(): void {
// Init your component properties here.
this.routerExtension.navigate(
[
{
outlets: {
featuredTab: ["featured"]
},
},
],
{ relativeTo: this.activeRoute }
)
}
}
home-routing.module.ts
...
const routes: Routes = [
{ path: '', redirectTo: "home", pathMatch: 'full' },
{
path: "home",
component: HomeComponent,
children: [
{
path: "featured",
component: NSEmptyOutletComponent,
loadChildren: () =>
import("~/app/home/featured/featured.module").then(
(m) => m.FeaturedModule
),
outlet: "featuredTab",
},
]
}]
...
And finally, the "featured" children tab component which defines the action bar (which takes up the space in the ios safe area)
featured.component.html
<ActionBar>
<NavigationButton visibility="hidden"></NavigationButton>
<GridLayout columns="50, *">
<Label class="action-bar-title" text="Home" colSpan="2"></Label>
<Label class="fas" text="" (tap)="openDrawer()"></Label>
</GridLayout>
</ActionBar>
<Label text="You are in featured component"></Label>
Github link for testing:
https://github.com/limyandi/fuzzy-octo-memory
I was facing a similar problem (but using BottomNavigationBar) and determined the issue was caused by lazy loading Modules (loadChildren) in app-routing.modules.ts. I worked around this by converting the module to a component and removing the lazy loading.
However, I like having my code organized into Modules and after a bit of digging found this was actually caused by including the property:
component: NSEmptyOutletComponent
Removing this property will fix the layout issue but introduces other subtle bugs. Instead this bug report eventually got me on the right track. I created the WrappedEmptyOutlet as an alternative to NSEmptyOutletComponent as shown in this repo and the layout problems have been resolved WITHOUT subtle side-effects so far :)

Routing problem when application is starting Ionic 4

We are developing an application with Ionic 4 with the framework Angular.
We have an issue when we log to the application.
You can see the error on the picture:
My code is here:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { TabsPage } from './tabs.page';
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'tab1',
children: [
{
path: '',
loadChildren: '../tab1/tab1.module#Tab1PageModule'
}
]
},
{
path: 'tab2',
children: [
{
path: '',
loadChildren: '../tab2/tab2.module#Tab2PageModule'
}
]
},
{
path: 'tab3',
children: [
{
path: '',
loadChildren: '../tab3/tab3.module#Tab3PageModule'
}
]
},
{
path: '',
redirectTo: '/tabs/tab2',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/tabs/tab2',
pathMatch: 'full'
}
];
#NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class TabsPageRoutingModule {}
I don't believe in magic but when i delete one dot on the loadchildren exemple :
../tab3/tab3.module#Tab3PageModule -> ./tab3/tab3.module#Tab3PageModule
I do it on all the loadchildreds I'm saving the page I try to log in, same problem
and after I reput the dot like this
./tab3/tab3.module#Tab3PageModule -> ../tab3/tab3.module#Tab3PageModule
I'm saving, I try to log in again and it works fine. With this problem, we can't compile on ios.
I think you have to resolve relative paths for your tabs. Use augury chrome to check and resolve your routing. Also try to simplify your routing.
{
path: 'tab2',
loadChildren: () => import('./tab2/tab2.module').then(m => m.Tab2PageModule)
},

Modify URL in asp.net zero

I have different tenants name and a login page whose path is localhost:4200/account/login but before that i have localhost:4200/account/workspace page where i will enter my tenantName in a textbox and the particular tenantId will be in the cookies. Now i want my next login page url to be like this
localhost:4200/tenantName/account/login and even after login i want the tenantName exactly there throughout the whole session. I am new to this and completely stuck here for 2 days. How can i modify my url here? This is problem is almost similar to this problem here.
https://forums.asp.net/t/2127416.aspx? How+to+modify+login+url+when+using+asp+net+identity
The difference is that i have to make changes in my front-end and not in the backend and its asp.net zero not asp.net core. Here is the code for my root-routing module file.
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: '', redirectTo: '/app/home', pathMatch: 'full' },
{
path: 'account',
loadChildren: 'account/account.module#AccountModule', //Lazy load account module
data: { preload: true }
},
{
path: 'app',
loadChildren: 'app/app.module#AppModule', //Lazy load account module
data: { preload: true }
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: []
})
export class RootRoutingModule { }

Resources