Is it recommended to include modules in the Imports section of SharedModule in Angular?

Welcome to my SharedModule!

import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { IconModule } from "@my-app/components/icon/icon.module";
import { RequiredActionDirective } from "@my-app/directives/required-action.directive";

@NgModule({
    imports: [
        CommonModule,
        IconModule
    ],
    declarations: [
        RequiredActionDirective
    ],
    exports: [
        CommonModule,
        IconModule,
        FormsModule,
        ReactiveFormsModule,
        RequiredActionDirective
    ]
})
export class SharedModule { }

I made the decision to include only CommonModule and IconModule in the Imports section because they are directly used in the RequiredActionDirective. However, I included more modules in the Exports section as they may be needed by other modules importing SharedModule.

It raises the question: is it correct that I do not have to add Modules to Imports unless directly using them in SharedModule? Could there potentially be unforeseen issues in the future despite everything working smoothly now?

Answer №1

It is important to be mindful when re-exporting modules and only import the necessary modules that the current module relies on. While importing poses no harm, exporting can create a division in the dependency tree for providers.

If a module re-exports another one, the parent module that imports it will not be able to override that import. This could potentially lead to issues in certain scenarios.

For instance;

@NgModule({
     imports: [HttpClientModule],
     provide: { provide: HTTP_INTERCEPTORS, useClass: ExampleInterceptor, multi: true },
     exports: [HttpClientModule]
})
export class SharedModule {}

In this case, AppModule will not be able to provide a different interceptor.

NgModule({
     imports: [SharedModule],
     provide: { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true }
     // ^^ interceptor is ignored
})
export class AppModule {}

The issue arises because the HttpClientModule is declared at the SharedModule level in the provider tree, which resolves all HTTP_INTERCEPTORS from that point onwards.

To address this, AppModule should import the HttpClientModule first, followed by the SharedModule.

NgModule({
     imports: [HttpClientModule, SharedModule],
     provide: { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true }
})
export class AppModule {}

By doing this, the HttpClientModule is now declared at the AppModule level, resolving all providers downwards, including those from the SharedModule. The sequence within the imports: [] array does not matter.

Answer №2

An NgModule has the ability to export a mix of its own declarations, specific imported classes, and NgModules that have been brought in.

It is unnecessary to re-export pure service modules as they do not contain declarable classes that can be utilized by another NgModule. For instance, there is no benefit in re-exporting HttpClientModule since it does not export any items. Its main purpose is to simply incorporate http service providers into the entire application.

Answer №3

Absolutely! It is possible to eliminate CommonModule from the imports in SharedModule. However, it's best to exercise caution as certain components may require it now or in the future.

Additionally, regarding CommonModule: Keep in mind that CommonModule gets automatically included in imports when generating a new module through CLI. While it can be safely removed since we already export it in SharedModule, it might come in handy for streamlining imports. Ultimately, the decision rests with you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The separator falls short of spanning the entire width of the page

For some reason, I can't seem to make the divider extend to the full length of the page. <TableRow> <TableCell className={classes.tableCell} colSpan={6}> <Box display="grid" gridTemplateColumn ...

The method Observable.combineLatest is not implemented

One of the features on my website is the Home page, where users can click on Contact me to navigate to the Contact page: home.component.html <div> <a routerLink="/contact" [queryParams]="sendOBj">Contact me</a> </div> home.comp ...

What are the drawbacks of combining exports through re-exporting in TypeScript?

Lately in TypeScript discussions, there seems to be a negative viewpoint on namespace BAD. However, I see value in organizing related declarations within a single namespace, similar to a library, to avoid excessive import statements. I have come across th ...

Tips for continuously running a loop function until retrieving a value from an API within a cypress project

Need help looping a function to retrieve the value from an API in my Cypress project. The goal is to call the API multiple times until we receive the desired value. let otpValue = ''; const loopFunc = () => { cy.request({ method: &ap ...

Svelte language switcher experiencing technical difficulties

Currently delving into Svelte 3, I embarked on a project intended to be shared on GitHub in English. However, I realized that some of my friends do not speak English. To accommodate different language preferences, I decided to create a language switcher. H ...

Error encountered in Angular 6 Application running on .Net Core within a Docker Container due to Npm issue

After developing an Angular 6 .Net Core 2.1 application that should be operational in a Linux Docker container, I encountered an issue when attempting to run it using docker compose. Strangely, the application works perfectly fine when launched with npm st ...

Guide to linking properties to Bootstrap 5 components within Angular

I am currently using Angular 13 along with Bootstrap 5. The bootstrap elements are functioning perfectly fine for static content. <button type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" title="Popo ...

What is the procedure for resetting the pagination tool?

What is the correct way to reset the paginator and navigate to the first page? Using this.page = 1 seems to be ineffective. It's worth mentioning that I am not utilizing MatPaginator. typescript: pageSizeOptions = [5, 10, 25, 50, 100]; pageSize ...

Having trouble connecting to the API due to the error "No Access-Control-Allow-Origin" in Angular 2

I am new to working with Angular2 and I'm currently facing a challenge in implementing authentication for an app using username and password login credentials. Unfortunately, I keep encountering the error message "No Access-Control-Allow-Origin". htt ...

Misunderstanding between Typescript and ElasticSearch Node Client

Working with: NodeJS v16.16.0 "@elastic/elasticsearch": "8.7.0", I am tasked with creating a function that can handle various bulk operations in NodeJS using Elasticsearch. The main objective is to ensure that the input for this funct ...

Using React, PIXI, and Zustand can sometimes lead to stale state issues when handling mouse events

I currently have a Pixi canvas that utilizes pointer handlers. Users are able to click on a point within a 'sequence' and move it. Recently, I came across an issue with the mouse handlers having stale state. To resolve this, I began recreating t ...

TypeORM: Create case-insensitive search functionality

Creating a basic search feature where the records are as follows: AB CD A BCD ABC D ABD C If the search term is "BCD", the expected output should be: AB CD A BCD ABC D The current query looks like this: await connection.manager .createQueryBuilder(RefTra ...

How to securely retrieve a document by integrating Angular 2 with a web API

I am currently working on an Angular 4 and web API application where I am attempting to download a file using Web API and TypeScript Blob. The code below showcases how this process is executed. However, upon trying to open the downloaded image, I encounter ...

Tips for packaging a Node TypeScript/JavaScript library using Webpack

I am currently working on a Node project with the following setup: Written in Typescript Using Webpack and ts-loader for bundling Targeting Node.js +-proj/ +-src/ |-file1.ts |-file2.ts |-file3.ts |-... |-package.json |-webpack.confi ...

Unable to transfer variable from a function to the test in Protractor

Currently, I am working on a test to verify the amount of gold in my possession. The test is being conducted using TypeScript and Protractor. Within this testing scenario, I have a method named GetAmountOfChips: public static GetAmountOfChips(): PromiseL ...

Injecting pipes into directives in Angular: A guide

I've developed a custom directive that formats input values based on the provided pipe parameter (@Input) in Angular reactive forms. For this functionality, I had to import the necessary pipes (currently just one) and implement a switch mechanism to ...

Avoiding Maximum Call Stack Size Exceeded in Observables: Tips and Tricks

After filtering, I have a list stored in the variable filteredEvents$: public filteredEvents$ = new BehaviorSubject([]); I also have a method that toggles the checked_export property and updates the list: public checkAll(): void { this.filteredEve ...

Ensure the JSON file aligns with the TypeScript Interface

I am working with a config.json file. { "profiler": { "port": 8001, "profilerCache": { "allowedOriginsRegex": ["^http:\/\/localhost:8080$", "i"] } }, "database": { "uri": "mongodb+srv://...", "dbName": "profiler", ...

Angular 7 error: Form control with name property does not have a valid value accessor

Currently, I am utilizing angular 7 and have a parent and child component set up as demonstrated in the Stackblitz link provided below. Strangely enough, when I assign the formControlName from the child component using "id", everything functions flawlessly ...

The imported variables are of a union type

In my nextjs project, I developed a customized hook to determine if a specific container is within the viewport using the intersection observer. Here's the code for the custom hook: import { useEffect, useRef, useState } from 'react'; cons ...