4
votes

Why Angular RouterModule uses forRoot() and forChild()?

I already read the article about forRoot pattern and how to defend provider singleton from multiple import (https://angular.io/guide/singleton-services#the-forroot-pattern) and I know why Routermodule uses forRoot().

But My question is, Why it uses both [ RouterModule.forRoot() <=> RouterModule.forChild() ] ? Is it not ok just using [ RouterModule.forRoot() <=> RouterModule ]?

Why angular developers forced users to write a few more alphabets for FORCHILD() ? Just for explicitness?

3

3 Answers

1
votes

The difference between forRoot() and forChild() :

  • forRoot() includes router services itself
  • forChild() doesn't include router services itself

So It's recommanded to use forRoot() in your 'root' module.

forChild() is used in your other module to optimize performance and don't reload router services for nothing.

https://angular.io/api/router/RouterModule#forChild

0
votes

RouterModule defines Providers and Declarations.

If a module defines both providers and declarations (components, directives, pipes), then loading the module in multiple feature modules would duplicate the registration of the service. This could result in multiple service instances and the service would no longer behave as a singleton.

Source: https://angular.io/guide/singleton-services

forRoot and forChild tells the module which parts to import, so you don't get multiple instances of services. Without a central service (a singleton), you'd get all kind of unexpected behaviour when accessing the service.

forChild prevents the import of the service, which otherwise would break the singleton.

0
votes

TR; DL: I misunderstood RouterModule. forChild() provides services that should not be provided by forRoot(). So forChild() can't be replaced by RouterModule.

Misunderstanding

After I read the source code of RouterModule, I realized that I had misunderstood.

RouterModule has only declarations(components, directives, pipes) and all services are provided from forRoot(). Then forChild() will be perfect subset of forRoot().

As a diagram:

So I was been wondering if only forRoot provides services and neither forChild() and RouterModule does not, then what's the difference between forChild() and RouterModule.

But I was wrong.

Correction

Unlike what I thought, forChild() was also providing services which should not be provided by forRoot(). One of the services provided by forChild() is user-defined routes, which should obviously have each instances.

And the correct diagarm looks like this:

I misunderstood because I've never seen services that should be provided multiple time, which its singleton could be destroyed.

Conclusion

There is a reason why forChild() is made separately.. forChild() is not a subset of forRoot(), and is clearly different with RouterModule itself.