barkin
barkin

Reputation: 351

How to instantiate Angular components with parameters?

I've been trying to instantiate components by passing parameters like nameFilter = new FilterComponent("Name"); but I'm getting this error:

NullInjectorError: No provider for String!

I believe dependency injection causes this as I don't get any errors if I don't inject anything to component. So what exactly causes this and how can I fix it?

Here's the component code

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

@Component({
     selector: 'app-filter',
     templateUrl: './filter.component.html',
     styleUrls: ['./filter.component.scss']
})
export class FilterComponent implements OnInit {
     title: String;

     constructor(title: String) {
          this.title = title;
     }

     ngOnInit() {
     }
}

Upvotes: 4

Views: 8528

Answers (2)

umutesen
umutesen

Reputation: 2640

The error is clear and you're right, the dependency injection mechanism is causing it. Every dependency you pass into the constructor must be injected at run-time and Angular needs to know what to pass in.

In your case, Angular does not know what to inject as the string title.

You can explicitly tell Angular what to inject in your module provider array for String type. However, this means that whatever you provide in the providers array will be used every time.

@NgComponent({
    ...
    providers: [
    { provide: String, useValue: 'my title' }
  ],
})

Having looked at your code, you can initialise the component with an @Input variable - Angular component interaction

export class FilterComponent implements OnInit {
     @Input() title: string; 
}

<app-filter [title]="Title 1"></app-filter>

Simple demo: https://stackblitz.com/edit/angular-rs6sfy

Upvotes: 2

ashish.gd
ashish.gd

Reputation: 1768

As a good design practice, avoid injecting primitive data types like string, number, date etc in component constructors.

But if you still need to inject them. Then you should let Angular know about the token and the value which is going to be injected.

For this Angular provides the InjectionToken API. https://angular.io/api/core/InjectionToken#injectiontoken

Example for injecting a date type in a component:

export const DATE = new InjectionToken<Date>('date');

@NgComponent({
    ...
    providers: [
    { provide: DATE, useValue: new Date() } //can be declared at the module as well
  ],
})
export class SomeComponent {

  constructor(
    @Inject(DATE) private fromDate: Date,
    @Inject(DATE) private toDate: Date
  ) {}

}

Upvotes: 3

Related Questions