'What is purpose of using forRoot in NgModule?

What is the purpose of using forRoot in NgModule?

Is it same as the providers in AngularJS 1.x?

How does it play the significant role in lazy loading?

TIA.



Solution 1:[1]

It has to do with singletons. Angular services are loaded onto the page 1 time (singleton) and all references point back to this 1 instance.

There is a risk that a lazy loaded module will try to create a 2nd instance of what should be a singleton, and the forRoot() method is a way to ensure that the app module / shared module / and any lazy loaded module all use the same 1 instance (the root instance).

More info copied from: Provide core singleton services module in Angular 2

The best approach is to create module with providers. Keep in mind that if your service is in shared module, you may get multiple instances of it. Best idea then is to configure module with Module.forRoot.

By convention, the forRoot static method both provides and configures services at the same time. It takes a service configuration object and returns a ModuleWithProviders.

Call forRoot only in the root application module, AppModule. Calling it in any other module, particularly in a lazy loaded module, is contrary to the intent and is likely to produce a runtime error.

Remember to import the result; don't add it to any other @NgModule list.

EDIT - FOUND SOME MORE INFORMATION ON THE ANGULAR DOCS IN REGARDS TO CODY'S QUESTION IN THE COMMENTS..

If a module provides both providers and declarations (components, directives, pipes) then loading it in a child injector such as a route, would duplicate the provider instances. The duplication of providers would cause issues as they would shadow the root instances, which are probably meant to be singletons. For this reason Angular provides a way to separate providers out of the module so that same module can be imported into the root module with providers and child modules without providers.

Create a static method forRoot() (by convention) on the module. Place the providers into the forRoot method as follows. To make this more concrete, consider the RouterModule as an example. RouterModule needs to provide the Router service, as well as the RouterOutlet directive. RouterModule has to be imported by the root application module so that the application has a Router and the application has at least one RouterOutlet. It also must be imported by the individual route components so that they can place RouterOutlet directives into their template for sub-routes.

If the RouterModule didn’t have forRoot() then each route component would instantiate a new Router instance, which would break the application as there can only be one Router. For this reason, the RouterModule has the RouterOutlet declaration so that it is available everywhere, but the Router provider is only in the forRoot(). The result is that the root application module imports RouterModule.forRoot(...) and gets a Router, whereas all route components import RouterModule which does not include the Router.

If you have a module which provides both providers and declarations, use this pattern to separate them out.

Solution 2:[2]

ForRoot()

forRoot() is used when we want to maintain a single instance (singleton)of a service across the application which will also have lazy loaded modules.

To give an example, take a look at this demo code where the counter is behaving differently for the eager and lazy loaded modules.

The counter is maintained by a CounterService which resides under SharedModule. Since, the lazy loaded modules creates its own instance of service, we lose the singleton behavior of the Angular Services.

To fix this, we need to introduce the concept of forRoot() . The working example can be seen here in this demo . This is the same reason, we use it with RouterModule to help RouterService understand the app behavior with several modules.

RouterModule.forRoot(ROUTES)

If you want a real-world example of how and where we can implement it, then this article will surely help you

Solution 3:[3]

From the docs

forRoot creates a module that contains all the directives, the given routes, and the router service itself.

You can read more on why is it used from here

Solution 4:[4]

There are two ways to create a routing module:

RouterModule.forRoot(routes)

creates a routing module that includes the router directives, the route configuration and the router service

RouterModule.forChild(routes)

creates a routing module that includes the router directives, the route configuration but not the router service. The RouterModule.forChild() method is needed when your application has multiple routing modules.

Remember that the router service takes care of synchronization between our application state and the browser URL. Instantiating multiple router services that interact with the same browser URL would lead to issues, so it is essential that there’s only one instance of the router service in our application, no matter how many routing modules we import in our application.

When we import a routing module that is created using RouterModule.forRoot(), Angular will instantiate the router service. When we import a routing module that’s created using RouterModule.forChild(), Angular will not instantiate the router service.

Therefore we can only use RouterModule.forRoot() once and use RouterModule.forChild() multiple times for additional routing modules.

Solution 5:[5]

forRoot() will be used to inject the providers at the top of the application. The instance of Component and directive are created a new instance everytime when they are invoked. When you mention the same at the root of the application (using forRoot()) only one instance will be created.

Firstly, we need to understand that providers are injected with some difference than that components and directives are injected. When a class is annotated with @Injectable, only one instance of this class will be created upon call and is shared throughout the entire application. To do so, we have to add this(forRoot()) method when the class is imported in NgModule.

Hope you are clear now.

Solution 6:[6]

The forRoot static method is the method that configures the root routing module for your app. When you call RouterModule.forRoot(routes), you are asking Angular to instantiate an instance of the Router class globally. Just like Angular creates a new base AppModule to import all of your feature modules, it also provides the AppRoutingModule to import all of your child routes.

In the new app that you have created via the Angular CLI, the forRoot method is actually already being used inside of the app-routing.module.ts. In your app, you only want to use the forRoot method once. This is because this method tells Angular to instantiate an instance of the Router class under the hood, and there can be only one router in your app. The forRoot static method is a part of a pattern that ensures that you are using singleton classes.

for more about this, check out the read more

Solution 7:[7]

ForRoot is used when a module is “eager,” that is, it is not lazy-loaded (loads when the application starts). Angular creates a factory for all the modules, except for the lazy modules, which when loaded on demand, have their own factory. When we use forRoot(), we’re loading a provider that is going to be injected into the “root” of the modules because it uses the same factory as our main module.

In simple terms, the use of forRoot allows us to access our providers from any point in the application that is not lazy loaded.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Shashank Vivek
Solution 3 Sajeetharan
Solution 4 Saeb Panahifar
Solution 5 Nandha King
Solution 6 Bhavesh Ajani
Solution 7 rohithpoya