Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Routing - ModuleWithProviders v NgModule

I'm working on a MEAN project via Angular 2, and am setting up the routing for my various pages. I've seen a lot of examples that use ModuleWithProviders to do routing, rather than the angular.io example with NgModule (https://angular.io/guide/router)

Which is the standard way of doing things? If either is acceptable, is there a performance difference between the two?

ModuleWithProviders example:

import { ModuleWithProviders } from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ServicesComponent } from './services/services.component';

export const router: Routes = [
    { path: '', redirectTo: 'about', pathMatch: 'full'},
    { path: 'about', component: AboutComponent },
    { path: 'services', component: ServicesComponent }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

NgModule Example:

import { NgModule } from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ServicesComponent } from './services/services.component';

export const router: Routes = [
    { path: '', redirectTo: 'about', pathMatch: 'full'},
    { path: 'about', component: AboutComponent },
    { path: 'services', component: ServicesComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot( router )
  ],
  exports: [
    RouterModule
  ]
})

export class AppRoutingModule {}
like image 560
austinthemassive Avatar asked Aug 22 '17 19:08

austinthemassive


People also ask

What is ModuleWithProviders in Angular?

ModuleWithProviders is the interface that is supposed to be returned by forRoot method. ModuleWithProviders object is plain object that has ngModule property that contains actual module class augmented with additional providers in providers property. Since ModuleWithProviders is an interface, its usage is optional.

What is difference between forRoot and forChild in Angular?

forRoot creates a module that contains all the directives, the given routes, and the router service itself. forChild creates a module that contains all the directives and the given routes, but does not include the router service. It registers the routers and uses the router service created at the root level.

What is RouterModule forRoot in Angular?

The forRoot() method creates an NgModule that contains all the directives, the given routes, and the Router service itself. The forChild() method creates an NgModule that contains all the directives and the given routes, but does not include the Router service.

How many types of NgModule are there?

There are two types of modules, root modules and feature modules. In the same way that in a module we have one root component and many possible secondary components, in an application we only have one root module and zero or many feature modules.


Video Answer


2 Answers

NgModule and ModuleWithProviders are different things.

NgModule is a decorator for module classes.

ModuleWithProviders is the interface that is supposed to be returned by forRoot method. ModuleWithProviders object is plain object that has ngModule property that contains actual module class augmented with additional providers in providers property.

Since ModuleWithProviders is an interface, its usage is optional.

like image 65
Estus Flask Avatar answered Nov 03 '22 01:11

Estus Flask


estus is absolutely right about the difference between the two (@NgModule is a decorator while ModuleWithProvider is an interface) but practically speaking, the answer to your question that which approach is better would be:

The second approach is more clear, more common and the best practice because it defines the routes in a separate module which it will be later imported to AppModule:

export const routes: Routes = [
    { path: '', redirectTo: 'about', pathMatch: 'full'},
    { path: 'about', component: AboutComponent },
    { path: 'services', component: ServicesComponent }
];

const config: ExtraOptions = {
  useHash: true
};

@NgModule({
  imports: [RouterModule.forRoot(routes, config)],
  exports: [RouterModule]
})    
export class AppRoutingModule {}

Importing to AppModule

@NgModule({
  declarations: [AppComponent],
  imports: [AppRoutingModule],
  bootstrap: [AppComponent],
})
export class AppModule {}

Although, what mentioned above hopefully answered your question, I like to also point out the difference between importing RouterModule in AppModule and sub-modules:

For the AppModule:

RouterModule.forRoot(routes)

For sub-modules:

RouterModule.forChild(routes)

Why? RouterModule gives you

  • a component (router-outlet)
  • a directive (routerLink)
  • also services (ActivatedRoute to get URL params, Router to navigate ...)

The first time in app module, forRoot will give the router components and provide the router services. But the next times in sub-modules, forChild will only give the router components (and not providing again the services, which are already available via the app module import).

Want to read more? I found this article amazing.

like image 24
Babak Avatar answered Nov 03 '22 01:11

Babak