DEV Community

Cover image for Passing Additional Parameters To An Angular Service
Leonel Elimpe
Leonel Elimpe

Posted on • Originally published at leonelngande.com on

Passing Additional Parameters To An Angular Service

If you want to pass additional parameters to an Angular service, what you are looking for is @Inject decorator. It helps you pass your parameters to the service through Angular’s dependency injection mechanism.

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected.

-- Rangle.io

Let’s say we’re writing a recaptcha service which requires the id of the recaptcha container in your html template, as below.

import {Inject, Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RecaptchaService {
    constructor (private recaptchaContainerId: string) { }
}

Enter fullscreen mode Exit fullscreen mode

Our example component:

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

@Component({
  selector: 'app-example',
  template: `
    <div id="recaptcha-container"></div>
  `,
})
export class ExampleComponent {

  constructor() { }

}

Enter fullscreen mode Exit fullscreen mode

How do we go about properly passing in the recaptchaContainerId to the service? Here’s how.

1 - We make an injection token out of the recaptchaContainerId parameter as follows:

import {Inject, Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RecaptchaService {
  constructor (
    // Make recaptchaContainerId an injection token
    @Inject('recaptchaContainerId') private recaptchaContainerId: string
  ) { }
}

Enter fullscreen mode Exit fullscreen mode

Injection tokens are a feature of Angular that allows the injection of values that don’t have a runtime representation. What we mean by this, is that you can’t inject something like an interface as it only exists as a TypeScript construct, not JavaScript. Injection tokens provide a simple mechanism to link a token, to a value, and have that value injected into a component.

-- Inversion of Control

2 - We then provide this token to the service through our component’s providers array as follows:

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

@Component({
  selector: 'app-example',
  template: `
    <div id="recaptcha-container"></div>
  `,
   providers: [
     // Provide a value to be used by Angular's dependency injection
     // machanism to pass 
    {provide: 'recaptchaContainerId', useValue: 'recaptcha-container'},
  ]
})
export class ExampleComponent {

  // We also inject our service
  constructor(private recaptchaService: RecaptchaService) { }

}

Enter fullscreen mode Exit fullscreen mode

Note that I’ve deliberately limited the scope of the provided recaptchaContainerId to this component due to the nature of such a token (an element id). In another component where RecaptchaService is injected, I might be using a different id.

It’s still very ok to provide the recaptchaContainerId token in the above component’s module or the root AppModule. More here.

And that’s it! We’ve successfully passed an additional parameter to an Angular service. Found something that can be improved? Please feel free to use the comment :-).

This Stackoverflow question served as a valuable guide in writing this blog post.

Top comments (1)

Collapse
 
andrewfinnell profile image
Andrew T. Finnell

This was exactly what I was looking for. Much appreciated.