Conditionally bind a property in Angular2/4

Viewed 2454

I want that a placeholder property (or any other) only gets into the DOM if it is defined. I tried

<textarea ... [placeholder]="value || null/false/undefined...etc" ... </textarea>

but these only show up as null, false, etc... as the text field's placeholder if value is not defined or null. (I know I could do "value || ' '" which would work for placeholders, but I'm looking for a more universal solution to keep any undefined property from getting into the DOM -as if [property]="... wouldn't be there at all.)

Why do I need this? Because my forms should be dynamic as placeholder and other attributes come from an interface and they don't necessarily have to be defined when they reach my template.

1 Answers

You can always create directive that will contain logic for setting placeholder attribute on host element:

import { Directive, ElementRef, Renderer2, Input } from '@angular/core';

@Directive({
  selector: '[placeholder]'
})
export class PlaceholderDirective {
  @Input() placeholder;

  constructor(private elRef: ElementRef, private renderer: Renderer2) {}

  ngOnChanges() {
    if(this.placeholder) {
      this.renderer.setAttribute(this.elRef.nativeElement, 'placeholder', this.placeholder);
    } else {
      this.renderer.removeAttribute(this.elRef.nativeElement, 'placeholder');
    }
  }
}

or we can simplify this directive like:

@Directive({
  selector: '[placeholder]'
})
export class PlaceholderDirective {
  @HostBinding('attr.placeholder') @Input() placeholder;
}

But you can always use attribute binding in your template:

<textarea [attr.placeholder]="null"></textarea>
Related