20858

Angular 2 constructor injection vs direct access

Q1. I have a common utility class with some utility/helper methods (no get/post request). First thing I have to ask is that whether it should be a simple class or an @Injectable class. Because both can be used after importing in any component class like this

import { Injectable } from '@angular/core'; Injectable() export class Utils { }

OR

export class Utils { }

Q2. If it's injectable then I have to import this in my component class, inject in the constructor, and must have to add in providers array then I can use any method of the injected class/service like

import { Utils } from './../shared/utils'; @Component({ moduleId: module.id, selector: 'abc', templateUrl: './abc.component.html', providers: [Utils] }) export class DemoComponent implements OnInit { constructor(private _u: Utils) { } ngOnInit(): void { this._u.someMethod(); } }

But beside this I can directly access the service methods without constructor injection and without having to add in providers, which is a short way like

import { Utils } from './../shared/utils'; @Component({ moduleId: module.id, selector: 'abc', templateUrl: './abc.component.html' }) export class DemoComponent implements OnInit { constructor() { } ngOnInit(): void { Utils.someMethod(); } }

So I wanted to know which one is better and recommended approach?

Answer1:

When you are using it in constructor,

<ol> <li>You use a separate instance of the service across your component.</li> <li>

When used as Injectable(), it should be declared inside the <strong>providers</strong> array of the module.

constructor(private _u: Utils) { } ngOnInit(): void { this._u.someMethod(); } //private - _u => is specific inside this component </li> </ol>

In case of direct access, the resources are used as it is which might create following problems

<ol> <li>Memory Leaks</li> <li>Less Reusability</li> <li>In case of observables, until an observable is unsubscribed you cannot subscribe to it again.</li> </ol>

Answer2:

Q1. @Injectable() is not required if Utils doesn't depends on any other service, but if it does you must use the @Injectable() decorator :

// 1 case @Injectable() // <--- required export class Utils { constructor(private _otherService : OtherService){} } // 2 case @Injectable() // <--- not required export class Utils { constructor(){} }

In both cases you have to add the service in the providers array of the component.

Q2. Use the first approach because it makes it easy to test your component by passing a MockUtils service.

Recommend

  • How to package resources so that they can be accessed from other Maven artifacts?
  • Concrete5 5.7: using a ServiceProvider cross-package
  • Do I need to clean user input for DB::query calls in laravel?
  • Extending a PrimeNg component inside Angular2
  • Can't remove inline event handler in chrome
  • Not getting updated value from model in events when implementing value accessor for custom controls
  • How to test method of JavaFX controller?
  • Building Yocto image for DragonBoard 410c, how to build Chromium
  • How can I make a circular menu icon? Please see details
  • How to “remove”/“change” some require(…) calls when using browserify?
  • How to inject service to class and then extend component with it?
  • How to reduce the time delay to reach run method of Runnable class using ExecutorService Java
  • Date format change angular 2
  • Angular2 emit event up to the DOM tree
  • Extending the Django 1.11 User Model
  • Running jasmine tests for a component with NgZone dependency
  • Less Conflicting Session Manager for Zope 2
  • iOS Cordova first plugin - plugin.xml to inject a feature
  • Why are YouTube videos using 'youtube.com/v' not loading
  • How to pass a value from ASP.NET MVC controller to ASP.NET webforms control inside MVC View?
  • Salesforce Different WSDL files and when to use
  • Ubuntu and bcrypt
  • Spring boot 2.0.0.M4 required a bean named 'entityManagerFactory' that could not be found
  • Specifying Castle WCF Integration Facility Endpoint Behavior per Endpoint
  • How can I set a binding to a Combox in a UserControl?
  • Create DicomImage from scratch using Dcmtk
  • Spring security and special characters
  • PHP - How to update data to MySQL when click a radio button
  • Is there a amazon webstore API for customers?
  • angularjs unit test when to use $rootScope.$new()
  • Trying to switch camera back to front but getting exception
  • Rearranging Cells in UITableView Bug & Saving Changes
  • Circular dependency while pushing http interceptor
  • Benchmarking RAM performance - UWP and C#
  • Free memory of cv::Mat loaded using FileStorage API
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Programmatically clearing map cache
  • UserPrincipal.Current returns apppool on IIS