Angular lazy loading - don't see it is working - javascript

I defined a lazy loading module.
this is SettingsRoutingModule module-
const routes: Routes = [
{
path: '',
component: SettingsStandaloneComponent,
children: [
{
path: '',
redirectTo: 'profile',
pathMatch: 'full'
},
{
path: 'profile',
component: SettingsProfileComponent
},
{
path: 'about',
component: SettingsAboutComponent
},
{
path: 'affiliations',
component: SettingsAffiliationsComponent
},
{
path: 'communication',
component: SettingsCommunicationComponent
},
{
path: 'notifications',
component: SettingsNotificationsComponent
},
{
path: 'proxies',
component: SettingsProxiesComponent
},
{
path: '**',
redirectTo: 'profile',
pathMatch: 'full'
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SettingsRoutingModule { }
in the AppRoutingModule module-
{ path: 'settings',
loadChildren: './settings/settings.module#SettingsModule',
canActivate: [AuthGuard],
},
in the prod production when a go to the network I don't see the "chunk.js" that everybody say that should appear". only two files that looks like- 0.34016a93d44e785b623a.js
In my localhost I see only "settings-settings-module.js"
Is it OK or does it mean that my module isn't lazy?

Because of this option "namedChunks": false in your angular.json, you won't see the named chunks anymore, instead it displays hashed-value as the file name. This is due to recent improvements(not sure from when) in angular/cli.

Yes it is OK, We do not see chunk.js anymore. A lazy loaded module appears with its name in network tab as mentioned by you and it appears only once for the first time. To see it again, clear everything out by clicking the circle with a line through it in the upper left of the Network Tab:

Make sure you're not filtering anything in Chrome Debugging tools in Network tab, it was driving me insane for a moment, I had everything set up perfectly.
Proof (I had 'fa' being filtered, that's why I couldn't see )
After

Related

How to fully reload an Angular component only when user is logged in?

In my Angular project I've got:
SignInComponent -> Handling the login requests
DashboardComponent -> Displayed for all children when user has successfully logged in
HomeComponent -> The actual content/page that will be displayed to the user - A child of 'DashboardComponent'
And it looks like:
export const appRoutes: Routes = [
{
path: 'login', component: SignInComponent
},
{
path: '', component: DashboardComponent,
children: [
{ path: '', component: HomeComponent },
],
canActivate: [AuthGuard]
},
{
path: '', redirectTo: '/login', pathMatch: 'prefix'
}
]
Now the problem that I'm facing, is that when the user is successfully logged in, that it won't reload the component 'DashboardComponent'. And I'm not referring to the routes itself (those are going fine). But there's one needed JS script not loaded which blocks the user from expanding the menu item(s). See below:
However, when you manually reload the page, it will work. The menu item(s) will expand. See below:
So, fully reloading the component would do the trick, but I only want that when it's matching with the previous 'route', in this case '/login'. In other words, I would to fully reload the 'DashboardComponent', only when it's not a 'child'. How could I apply this?
Or is there perhaps a better and easier approach?
Here it looks some url match problem because you have defined path:'' to dashboard also making that path to redirect to login with next routing object in routes array
export const appRoutes: Routes = [
{
path: 'login', component: SignInComponent
},
{
path: 'dashboard', component: DashboardComponent,
children: [
{ path: 'home', component: HomeComponent },
],
canActivate: [AuthGuard]
},
{
path: '', redirectTo: '/login', pathMatch: 'prefix'
}
]
So change it like above code and try. This will not make any url confusion and redirection will take place properly
Update:
It seems that custom code (JS) is being called on document ready event. That explains why it's working the only first time. See comment: https://stackoverflow.com/a/46349639/2318669.
What I've done to solve it:
I declared a variable:
declare const openMobileMenu: any;
And then I bind it from the component:
onMobile() {
openMobileMenu();
}
To the following method in the JS file:
function openMobileMenu() {
$(".horizontal-menu .bottom-navbar").toggleClass("header-toggled");
};
Thanks anyway for the support! :)
I appreciate it.

Angular 6 conflict in router links on same root

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'.

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 Routes meaning of plus and sharp symbol in augular starter?

Repo is https://github.com/AngularClass/angular-starter
I saw all these + and # for referencing inside loadChildren as well as naming inside the folder...
Went to angular reference https://angular.io/api/router/LoadChildren saw NOTHING about these sort of convention.
The hash (#) is part of the loadChildren syntax. It separates the path to the lazy loaded module from the class name of the lazy loaded module. Here is an example:
#NgModule({
imports: [
RouterModule.forRoot([
{ path: 'welcome', component: WelcomeComponent },
{
path: 'products',
canActivate: [ AuthGuard ],
data: { preload: true },
loadChildren: 'app/products/product.module#ProductModule'
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
]
],
exports: [ RouterModule ]
})
export class AppRoutingModule { }
The + may just be a symbol used in the folder name. I have not seen that usage before but it may mean something to that particular team.

Incorrect URL with named routing outlet in Angular 2

I am writing following code for routing:
imports: [
RouterModule.forChild([{
path: 'list/open',
component: SWAOrderAppComponent,
children: []
}, {
path: 'list/:orderId',
component: SWAOrderPackageComponent,
outlet: 'popup'
}, {
path: '',
redirectTo: 'list',
pathMatch: 'full',
}])],
exports: [RouterModule,]
and using following code to navigate to route "list/911" with named outlet 'popup'
this.router.navigate([{ outlets: { popup: "list/"+ id }}]);
This is loading correct component but i am getting following url with this route:
https://host/list(popup:list/911)
I want URL of format
https://host/list/911

Categories