I have developed an angular 4 web application, which has 3 components and all are independent components.
LoginPage
FormPage
Dashboard
LoginPage and FormPage are small components but Dashboard is a very big module.
My problems is i don't want to download the entire main bundle(1.5mb) on the login page (on page load which takes more time to download entire content) . i want to download the dashboard component related JS file chunk on dashboard component loading.
I am using ng-build --prod for production build
Is it possible to split the main bundle js based on component? Can I do the same split in vendor JS too?
You can have lazyloaded modules using Angular router loadChildren. Based on user access URL, their corresponding module will be loaded on demand.
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
const app_routes: Routes = [
{
path: 'login',
loadChildren: 'app/login/login.module#LoginModule'
},
{
path: 'dashboard',
loadChildren: 'app/dashboard/dashboard.module#DashboardModule'
},
{ path: '', pathMatch: 'full', redirectTo: '/login' },
{ path: '**', pathMatch: 'full', redirectTo: '/login' }
];
#NgModule({
imports: [RouterModule.forRoot(app_routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Related
when I reload the page when I'm on lazy loaded module the app breaks as it tries to import js files from the wrong path. you can see my routing configuration:
app routing module:
{
path: 'accommodations',
canActivate: [AuthGuard],
loadChildren: () => import('./accommodation/accommodation.module').then(m => m.AccommodationModule)
}
accommodation routing module:
const routes: Routes = [
{
path: ':id',
component: AccommodationDetailsComponent
}
];
when I'm on route http://localhost:4200/accommodations/1 for example and I reload the page, browser tries to import js files from http://localhost:4200/accommodations and shows 404 error.
for example, it tries to import runtime js from http://localhost:4200/accommodations/runtime.js
I didnt' find the problem itself, but i found that if I use useHash:true the error goes away
Im using Angular 7 + router. For example, my home page is localhost:4200, one of my router's url is localhost:4200/route and I have an API end point at localhost:4200/api/foo.
I'm trying to let the browser load the api end point from both locations. If I put an anchor with href pointing to the API end point, both anchor link works perfectly. However, I need to do it programmatically and I have tried all of the following methods
window.open("localhost:4200/api/foo","_self")
window.location.replace('localhost:4200/api/foo');
window.location.href = 'localhost:4200/api/foo';
They all works on the home page but if I'm in the router page, doing so will get me to the home page.
Any help is greatly appreciated!
To be specific, I have a spring boot server with url patterns like /api/*. All other urls are handled by angular. I want the browser to load localhost:4200/api/foo, which is directly handled by a get request defined in the server
Demo:
My nav bar is a component and it stays the same regardless of the router.
The code behind that button click is below. Note that the first time I click it under some Angular routed url, it loads the home page, not google.com
onLogIn() {
window.open('https://www.google.com',"_self");
}
Routing.ts file
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { IndexComponent } from "./index/index.component";
import { MicroserviceComponent } from "./microservice/microservice.component";
const routes: Routes = [
{ path: '', component: IndexComponent},
{ path: 'microservice/:id', component: MicroserviceComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
add pathMatch to your empty route, it's missing tht's why you're redirected to the home component
const routes: Routes = [
{ path: '', component: IndexComponent, pathMatch:'full'},
{ path: 'microservice/:id', component: MicroserviceComponent}
];
I'd like to load an Angular app using lazy-loading (when a specific route is hit by users) into another Angular app
Shall I compile the first app in order to be used into the second one or what?
Routing-Module of the app to nest into an Angular app:
const upgradeRoutes: Routes = [
{
path: '/upgrade',
component: HelloComponent
},
{ path: '', redirectTo: '/upgrade', pathMatch: 'full' }
];
#NgModule({
imports: [
RouterModule.forChild(upgradeRoutes)
],
exports: [
RouterModule
],
declarations: []
})
export class UpgradeRoutingModule { }
Module of the app to nest into an Angular app
#NgModule({
declarations: [
AppComponent,
HelloComponent
],
imports: [
CommonModule,
UpgradeRoutingModule
],
exports: [
UpgradeModule
],
providers: [],
bootstrap: [AppComponent]
})
export class UpgradeModule { }
App module where I want to use (with lazy loading) the first one described in a child routes:
import {UpgradeModule} from '../../node_modules/module-upgrade/src/app/app.module'
#NgModule({
declarations: [
...
],
import: [ UpgradeModule ]
});
1) I'd like to understand if that is correct, and/or there is another way to do it.
2) Another problem is that the child app uses Angualr 6, whereas the second/main one uses Angular 4.
Either:
Don't bootstrap your child app and use it as a submodule (that requires that you upgrade the main app to Angular 6, which requires at least to refactor your RxJS operators calls, and probably some minor other things),
Or just configure your web server to serve your child app on a specific URL. In that case your two apps won't be able to share any state (except global namespace, cookies and localStorage) or
Angular Component/Service/Directive/Pipe
I am using Ionic 3 and angular 5. I have one feature module 'Settings':
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { SettingsPage } from './test';
#NgModule({
declarations: [
SettingsPage,
],
imports: [
IonicPageModule.forChild(SettingsPage),
],
})
export class SettingsPageModule {}
Under Settings module I want to add 5 more pages.
I checked a lot of post and cannot found out how to do that. Is it even possible ?
The Ionic3 standard way, if you use lazy loading, is: one module per page.
If you use the CLI, ionic generate page command will do the job for you and create a folder with 4 files whenever you create a new page.
If you don't want pages to live each in a separate directory, one way could be to create the new page-related files in the same directory.
But, if you want multiple pages in one module, it's not going to work, at least in my experience - e.g. if you try to place two pages in the same directory and load them from the same module, you'll get this error message:
Error: /.../src/pages/pagegroup/pageX.ts has a #IonicPage decorator, but it does not have a corresponding "NgModule" at /.../src/pages/pagegroup/pageX.module.ts
Below I'm explaining a working solution to have multiple pages, each with its own module, in a single directory.
Let's assume you start from this:
src
settings
settings.html
settings.module.ts
settings.scss
settings.ts
...and you want to add a page named "CustomSettingsPage".
Depending on how complex this page is, you must add the following 2 to 4 files, in the same directory (src/settings) - the optional ones are between square braces:
[custom-settings.html]
custom-settings.module.ts
[custom-settings.scss]
custom-settings.ts
The module and page .ts files will have a similar structure:
custom-settings.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { CustomSettingsPage } from './custom-settings';
#NgModule({
declarations: [
CustomSettingsPage,
],
imports: [
IonicPageModule.forChild(CustomSettingsPage),
],
exports: [
CustomSettingsPage
]
})
export class CustomSettingsPageModule {}
custom-settings.ts
import { Component } from '#angular/core';
import { IonicPage } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-custom-settings',
template: `<your html template here>`
})
export class CustomSettingsPage {
// your page code here
};
Instead of template: you could use templateURL: 'custom-settings.html' - in that case, you should create the corresponding custom-settings.html template file in the same directory.
If you want to add the CSS rules for this page, you can create an optional custom-settings.scss file like:
.page-custom-settings {
/* your rules here */
}
or, you can add those CSS rules to the existing settings.scss file: this is really up to you.
I believe what you want is "modals"
https://ionicframework.com/docs/components/#modals
You can add individual pages under your settings.
I'm late to this question but just in case someone needs it in the future!
I'm not sure if you are referring to this but you can have several pages into one module having a folder tree like, for example:
pages
settings
childPage 1
child1.page.(html|scss|ts)
childPage 1
child1.page.(html|scss|ts)
settings.module.ts
settings.page.(html|scss|ts)
then in your Setting Routing Module you do like
import ...
const routes: Routes = [{
path: '',
redirectTo: 'pathtoRedirect', // if you need it
pathMatch: 'full'
}, {
path: '',
component: SettingsPage
}, {
path: 'child-page-1',
component: ChildPage1
}, {
path: 'child-page-2',
component: ChildPage2
}]
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SettingsPageModule {}
Then in your App Routing Module you can do something like:
import ...
const routes: Routes = [{
...
}, {
path: 'settings',
loadChildren: () => import('./pages/settings/settings.module').then(m => m.SettingsPageModule),
}, {
...
}]
#NgModule({
...
})
export class AppRoutingModule{}
This should work. What a component needs is for it to be in ANY module. It's true "module per page strategy" is included as best practice, however, sometimes I simply don't want to have many files that actually can be deleted and managed under the same module.
From this point, you can have a different folder tree if you feel like it, or even create a deeper nested route like
/settings
/settings/children/:id
/settings/children/otherchildren/childrenpage
Now it would be up to you and your project needs!
Hope this is useful for somebody!
I have doubt in routing in angular2.
I have a login screen. After login dashboard and other pages had header and footer which will not be in login.
const routes: Routes = [
{
path:'',
redirectTo: '/login',
pathMatch: 'full'
},
{
path:'login',
loadChildren: './auth/auth.module#AuthModule',
},
{
path: 'dash',
loadChildren: './dash/dash.module#DashModule',
canActivate:[AuthGuard],
data: {
preload: true
}
},
{
path: 'project',
loadChildren: './project/project.module#projectModule',
canActivate: [AuthGuard],
data: {
preload: true
}
}
];
So its loading to the router-outlet in the app.component.html.
Currently I have to use the header component in all module html, like in dash.component.html
<ks-header></ks-header>
<router-outlet></router-outlet>
This router-outlet is a child outlet on which other dash related load.
Same like for other modules.
Is there any other effective way to show common header/sidebar?
I tried it in app.component.html like
<ks-header [userInfo] ="userInfo" [hidden]="isLogin"></ks-header>
<ks-sidebar [hidden]="isLogin"></ks-sidebar>
the islogin will determine logined or not. But I don't think it's a good idea.
You should use nested routes.
One for the base, as routeing between the template page and the login page.
The second and the nested one must be accomplished routeing between templated pages like
HOME, ABOUT, CONTACT ...
You can learn more about nested routes from here. So simple explanation.
And there is another question similar to yours. Namek's answer seems useful.