How To Use Typescripts …SpreadOperator In Angular

Blog post #004

Duncan Faulkner – February 2020

Recently I’ve found myself looking at ways I can improve the reading of my code. Just little things, just to tweak this or that just to make the code a little more easier on the eye.

Recently I’ve started using the spread operator (…) as I find this looks a lot cleaner and makes code easier to read.

In this post I’m going to show you how to use the spread operator in your Angular module files.

Most of the module files I’ve written have all looked the same. Starting at the top of the file are the Imports, followed by the NgModule with some or all of the following: Imports, Exports, Declarations, Entry Components and Providers.

Depending on the number of imports into the module this can have a lot of repeated code. So these files are ideal for the spread operator, reducing the repeated code. Lets see and example.

import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';

import { NgModule } from '@angular/core';

@NgModule({
  imports: [
    MatAutocompleteModule,
    MatButtonModule,
    MatButtonToggleModule,
    MatCardModule,
    MatCheckboxModule,
    MatChipsModule
  ],

  declarations: [],
  exports: [
    MatAutocompleteModule,
    MatButtonModule,
    MatButtonToggleModule,
    MatCardModule,
    MatCheckboxModule,
    MatChipsModule
  ],
  entryComponents: [],
  providers: [MatIconRegistry]
})
export class MaterialModule { }

The above example is from the Mat-Icon material module file and shows the same things repeated three times in this example. Lets refactor this code.

import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';

import { NgModule } from '@angular/core';

const MODULES = [
  MatAutocompleteModule,
  MatButtonModule,
  MatButtonToggleModule,
  MatCardModule,
  MatCheckboxModule,
  MatChipsModule
];
@NgModule({
  imports: [
    ...MODULES
  ],
  declarations: [],
  exports: [
   ...MODULES
  ],
  entryComponents: [],
  providers: [MatIconRegistry]
})
export class MaterialModule { }

Now, unfortunately the Angular Material imports need to be individually imported for each feature separately, but it does reduce the code (a bit) and it does help with having just one copy to manage, lets have another example, that I have changed to use the spread operator (you should be able to visualise what this looked like before).

import { NgModule } from '@angular/core';
import { VendorModule } from './vendor.module';

import {
  AnalysisComponent,
  ChartComponent,
  IconComponent,
  PodComponent,
  SpinnerComponent,
  TermsComponent,
  ChangePasswordComponent
} from './components';

import {
  PortPipe,
  NumericPipe,
  AsteriskPipe,
  SplitIpPipe,
  RemoveUnderscorePipe,
  AddUnderscorePipe,
  FormatBytesPipe
} from './pipes';

import { NumberDirective } from './directives';

const COMPONENTS = [
  AnalysisComponent,
  ChartComponent,
  IconComponent,
  PodComponent,
  SpinnerComponent,
  TermsComponent,
  ChangePasswordComponent
];

const PIPES = [
  PortPipe,
  NumericPipe,
  AsteriskPipe,
  SplitIpPipe,
  RemoveUnderscorePipe,
  AddUnderscorePipe,
  FormatBytesPipe
];

const DIRECTIVES = [NumberDirective];

const MODULES = [VendorModule];

const ENTRYCOMPONENTS = [TermsComponent, ChangePasswordComponent];

@NgModule({
  imports: [...MODULES],
  declarations: [...COMPONENTS, ...PIPES, ...DIRECTIVES],
  exports: [...COMPONENTS, ...PIPES, ...DIRECTIVES, ...MODULES],
  entryComponents: [...ENTRYCOMPONENTS],
  providers: [...PIPES]
})
export class SharedModule {}

In the example above, imports for the component, pipes and directives are all grouped together. Constants are configured, and used in the NgModule section of the file . The important part of this file is the NgModule section and you can easily now read that section without all the clutter of all the various components, pipes and directives all over the place.

The spread operator include options for object destructing, rest params and array destructing (as shown above).

Thanks for reading!


Previous Posts…

2 thoughts on “How To Use Typescripts …SpreadOperator In Angular”

Leave a Reply

Your email address will not be published. Required fields are marked *