Michal
Michal

Reputation: 5220

Trigger Module Lazy Load Manually Angular 7

Official documentation has quite a lot of information about how to load angular modules lazily. [link here]

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: './customers/customers.module#CustomersModule'
  },
  {
    path: 'orders',
    loadChildren: './orders/orders.module#OrdersModule'
  },
  {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];

This basically makes the module load when user visits /customers or /orders routes.

However, I can't figure out how do I load a module when from another module.

In my application I have these modules:

One route of my auth module (profile page) has to use ngrx store from events module.

My code looks like this:

import { Observable } from 'rxjs';

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';

import { AppState } from '../../app.store';
import { IUser } from '../auth.api.service';
import { selectUser } from '../store/auth.selectors';
import { IEvent } from '../../events/events.api.service';
import { selectAllEvents, selectIsLoading } from '../../events/store/events.selectors';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.scss'],
})
export class ProfileComponent implements OnInit {
  isLoading$: Observable<boolean>;
  events$: Observable<IEvent[]>;
  user$: Observable<IUser>;

  constructor(
    private store: Store<AppState>,
  ) {
    this.user$ = this.store.select(selectUser);
    this.isLoading$ = this.store.select(selectIsLoading);
    this.events$ = this.store.select(selectAllEvents);
  }

  ngOnInit() {
  }

}

However, as you can expect this code does not work. Because ../../events is not loaded yet. How do I load the module manually? Something like:

constructor(
  private store: Store<AppState>,
) {
  this.user$ = this.store.select(selectUser);
  this.loadModule('../../events/events.module.ts').then(() => {
    this.isLoading$ = this.store.select(selectIsLoading);
    this.events$ = this.store.select(selectAllEvents);  
  })
}

Upvotes: 0

Views: 1019

Answers (2)

Sachin Gupta
Sachin Gupta

Reputation: 5311

You need not worry about loading the ../../events. Since you have the import statement, the class/interface would be available in the module. If for some reason, you want to use features of other modules, you can add the module name in the imports array in the @NgModule declaration.

Upvotes: 1

DeborahK
DeborahK

Reputation: 60518

The Angular CLI bundler bundles up the modules based on two things:

1) If you have the modules set up for lazy loading (loadChildren), it will bundle the module up separately and provide it lazily.

2) HOWEVER, if there are any references to a lazy loaded module in any other module (by adding it to its imports array), it instead bundles the module with the referenced component.

So what should be happening is that if your events module is referenced from a component, it should be bundled with that component.

Do you have the module referenced in the imports array for the module containing the component that references it?

What error are you getting exactly?

BTW - I cover this in the "lazy loading" part of this talk: https://www.youtube.com/watch?v=LaIAHOSKHCQ&t=1120s

Upvotes: 1

Related Questions