Using Objects with Angular @Input Properties | Task

Ole Ersoy
Aug - 23  -  2 min

Scenario

We are using the following Config class to configure our component.

export type Language = 'javascript' | 'typescript' | 'elixir';
export class Config {
    name: string = 'RxJS';
    responsive: boolean = true;
    language: Language = 'typescript';
}

We want to configure it using an @Input() property like this:

[config]="{ name: 'Firefly Semantics Slice',
            language: 'typescript',
            responsive: true }"

Approach

In order to demo this we will alter the Stackblitz hello component slightly adding the config @Input property.

export class Config {
  name: string = 'RxJS';
  responsive: boolean = true;
  language: Language = 'typescript';
}

@Component({
  selector: 'hello',
  template: `<h1>Hello {{config.name}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements AfterViewInit {
  @Input() config: Config;

  ngAfterViewInit() {
    console.log(this.config);
  }
}

Now we can configure instances of the HelloComponent component like this.

<hello
  [config]="{
    name: 'Firefly Semantics Slice',
    language: 'typescript',
    responsive: true
  }"
></hello>

<hello
  [config]="{ name: name, language: 'typescript', responsive: false }"
></hello>

Note that in the last hello declaration within the app.component.html template we are interpolating the name property directly into the config object.

<hello [config]="{ name: name, language: 'typescript', responsive: false }">
</hello>

Note that if we leave off a property like name we will get an error.

Property 'name' is missing in type '{ language: "typescript"; responsive: true; }' but required in type 'Config'

We can make properties optional by using a Partial and a setter like this (Note that we have moved @Input above set ).

_config: Config = new Config();
@Input()
set config(c: Partial<Config>) {
    this._config = Object.assign(this._config, c);
}
get config() {
    return this._config;
}

Demo

With Partial.