Created
October 30, 2016 11:20
Providing Run Blocks Using A Service Constructor In Angular 2.1.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import the core angular services. | |
import { APP_INITIALIZER } from "@angular/core"; | |
import { BrowserModule } from "@angular/platform-browser"; | |
import { ErrorHandler } from "@angular/core"; | |
import { Injectable } from "@angular/core"; | |
import { NgModule } from "@angular/core"; | |
// Import the application components and services. | |
import { AppComponent } from "./app.component"; | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
@Injectable() | |
export class OnRun { | |
// Because this is a "class" and not a Factory function, we can use the normal | |
// dependency-injection semantics. All we have to do is define Types here and those | |
// instances will be provided to the constructor. | |
constructor( errorHandler: ErrorHandler ) { | |
// CAUTION: Here, we are "hacking" the workflow. Instead of letting Angular use | |
// the OnRun class instance, we're explicitly overriding the constructor method's | |
// return value, passing back the "run block". This is a core feature of | |
// JavaScript's "newable" Functions (from MDN): | |
// -- | |
// >> The object returned by the constructor function becomes the | |
// >> result of the whole new expression. If the constructor function | |
// >> doesn't explicitly return an object, the object created in step 1 | |
// >> is used instead. (Normally constructors don't return a value, | |
// >> but they can choose to do so if they want to override the normal | |
// >> object creation process.) | |
// -- | |
return( runblock ); | |
// NOTE: This is the method that gets run at the end of the bootstrapping process. | |
function runblock() : void { | |
console.group( "Class Instance" ); | |
console.log( "Run block generated by class instance (return value)." ); | |
console.log( errorHandler ); | |
console.groupEnd(); | |
} | |
} | |
} | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
@NgModule({ | |
bootstrap: [ AppComponent ], | |
imports: [ BrowserModule ], | |
providers: [ | |
OnRun, | |
// Here, we are defining an app initializer or "run block" using a factory | |
// function. The factory function returns a Function reference which will be | |
// invoked at the end of the bootstrapping process. Notice that the factory | |
// function can use dependency-injection using the "deps" array. | |
{ | |
provide: APP_INITIALIZER, | |
multi: true, | |
deps: [ ErrorHandler ], | |
useFactory: function( errorHandler: ErrorHandler ) : () => void { | |
return( runblock ); | |
// NOTE: This is the method that gets run at the end of the | |
// bootstrapping process. | |
function runblock() : void { | |
console.group( "Factory Function" ); | |
console.log( "Run block generated by Factory function." ); | |
console.log( errorHandler ); | |
console.groupEnd(); | |
} | |
} | |
}, | |
// As it turns out, we can also define app initializers as classes. Sort of. | |
// Ultimately, we still need to return a Function reference; but, we can leverage | |
// the Class mechanics to drive the dependency-injection as long as the class | |
// constructor still returns the Function reference that gets invoked at the end | |
// of the bootstrapping process. | |
{ | |
provide: APP_INITIALIZER, | |
multi: true, | |
useClass: OnRun | |
} | |
], | |
declarations: [ AppComponent ] | |
}) | |
export class AppModule { | |
// ... nothing to do here. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment