Making a getter @bindable

This is a simplified example.

Let’s say we have a name input component that has input boxes for the firstName and lastName. But we don’t care about these separate variables, only the combined fullName. We want to be able to get that value from the custom component.

<name-input full-name.from-view="customerName">

Intuitively, you use a computedFrom getter for this:

@customElement("name-input")
class NameInput{
  private firstName: string;
  private lastName: string;
  
  @computedFrom("firstName", "lastName")
  public get fullName() { return this.firstName + " " + this.lastName; }
}

This is not yet bindable to the outside, so we add a bindable, that only allows data to flow from the component to the outside, not the other way:

class NameInput{
  private firstName: string;
  private lastName: string;
  
  @bindable({defaultBindingMode: "fromView"})
  @computedFrom("firstName", "lastName")
  public get fullName() { return this.firstName + " " + this.lastName; }
}

This does not work…

Also not having only bindable there, or only computedFrom. A getter cannot be bound in Aurelia it seems.

Current solution

Turn it into a normal variable.
To mimic the computedFrom we need to turn firstName and lastName into observables and recalculate fullName manually.

class NameInput{
  @observable
  private firstName: string;
  @observable
  private lastName: string;
  
  @bindable({defaultBindingMode: "fromView"})
  public fullName: string;
  
  private setfullName(): void
  {
    this.fullName = this.firstName + " " + this.lastName;
  }
  
  private firstNameChanged(): void
  {
    setFullName();
  }
  private lastNamechanged(): void
  {
    setFullName();
  }
}

This solution is far from ideal, having 3 functions and a variable, when 1 getter would do. If the computedFrom has more variables, this will grow large very quickly.

Are there any better solutions?

Hello, this is not a solution but I understand that in Aurelia 2, the framework automatically computes observation without the need for any configuration!

You can avoid duplication by using the same change handler for all the observables.

@observable({ changeHandler: 'setfullName' })
private firstName: string;

@observable({ changeHandler: 'setfullName' })
private lastName: string;
1 Like