DEV Community

Jacques Begin
Jacques Begin

Posted on

Angular Binding Refactor, get rid of the extra code

I've been getting started in the Angular world and have really been impressed how it can reduce the amount of code for simple tasks.

While working through the binding section of "Angular 8 - The Complete Guide" (course on Udemy by Maximilian Schwarzmüller), I learned that by adding code to the bindings themselves, a fair bit of code could be eliminated in the component's typescript file.

To practice using bindings I created:

  • Input field to take a username (with ngModel to update the username value)
  • <p> element to output the name (using string interpolation)
  • Button to clear the input field (keep disabled if username is empty)

The component's html file looked like this:

<label>Username</label>

<input
type="text"
(input)="onInputUsername($event)"
[(ngModel)]="username">

<p>{{ username }}</p>

<button
[disabled]="usernameEmpty"
(click)="onClickClearUsername()">Submit</button>

The input event called onInputUsername($event) and was used to check if the input had a value and set a boolean accordingly.

The button event called onClickUsername() and was used to clear the input field when clicked.

You can see these in action in the component's typescript file:

export class BindingComponent {
  username: string = "";
  usernameEmpty: boolean = true;

  onInputUsername(event: Event) {
    if ((<HTMLInputElement>event.target).value !== "") {
      this.usernameEmpty = false;
    } else {
      this.usernameEmpty = true;
    };
  }

  onClickClearUsername() {
    this.username = "";
    this.usernameEmpty = true;
  }
}

As written, the code accomplished what I had intended; take in a username, display the username, and remove the username. But upon refactoring the code, it became apparent that Angular is capable of doing much of this work right in the bindings themselves.

Instead of creating events to call component functions all that was necessary was to set property values as part of those bindings.

The input's event could be removed completely and instead just be responsible for receiving input.

<input
type="text"
[(ngModel)]="username">

The button's disabled property could be bound directly to the value of username thus triggering it's active state when username had a value. Also, the click event would no longer need to call onClickClearUsername() and instead set the value of username to "" (empty string) when fired.

<button
[disabled]="username === ''"
(click)="username = ''">Submit</button>

Check out the refactored work!

HTML file:

<label>Username</label>

<input
type="text"
[(ngModel)]="username">

<p>{{ username }}</p>

<button
[disabled]="username === ''"
(click)="username = ''">Submit</button>

Typescript file

export class BindingComponent {
  username: string = "";

}

By moving most of the work into the bindings the typescript file was reduced down to 1 property and an unnecessary event was removed from the HTML.

The "magic" of Angular is a beautiful thing 🧙‍♂️🔮

Top comments (0)