loading...

Readonly inputs for primitives properties in Widgets for Angular

michaeljota profile image Michael De Abreu 惻3 min read

Hi! It's me again. Today I'm releasing the first stable version of my Pomodoro application. I made it using Angular 4, and Electron. While I was developing it, I try to use TDD, use a ngrx/Store, and separate the components of the Widgets, and use the @Input-set, and template-get for manage data.

But I have to say it, I failed, I failed big time. First at all, I come to realize why TDD is a design pattern, if you don't have defined what you want to do, you can't test first. I try to use the Store, but at the end I managed all the state from one component. But I did use Widgets to display the content, where I could. Well, this is actually the first application I do by my self, so, don't be mean. I've been working with AngularJS since 1.2, and with Angular since RC5, but I never had to design the functionality of the app, the business logic was a piece of the company I'd worked on.

However, where I failed the most was at using the @Input-set/template-get duo. I mean, I could use them, but I most manage primitives values, so why bother? Still, one advantage of this approach is that you could treat the values as inmutables, because you set it somewhere, and return it somewhere else, there is no place to side effects there.

So how to deal with primitives, without written unnecessary code lines, and still maintaining the immutability? Well, Typescript 2 brought a nice feature to deal with this readonly modifier. You can read more about that here. It is different from a const, cause the assignment check it's doing in compilation time, instead of runtime. Meaning, that even if you set your property to readonly, in runtime in can be written as many times as needed. But this approach allows us to be sure that the property will be only written by the inputed value, and we ain't going to modify it.

export enum Cicle {
  // Cicle values
}

@Component({
  // Component definitions
})
export class StartButtonWidget {
  @Input()
  public readonly cicle: Cicle;
  @Output()
  public onClick: EventEmitter<Cicle> = new EventEmitter<Cicle>();

  public get label(): string {
    // Returns a strings from the value of the cicle
  }

  public emit(): void {
    this.onClick.emit(this.cicle);
  }
}

As you can see, using a readonly property for our input primitives allow us to be sure about how and when it's the property changing. But, I still think this have a disadvantage. If you need to input a value, and display another value, you could accidentally access the property in a wrong way. And I don't mean you exactly, but the team you work in. With the @input-set/template-get the intentions you have when you write are clears, but with this, you have to be sure that the primitive is going to be use the way you expect. Documentation would be do it, I think.

This is just another way to deals with properties in Typescript and Angular framework, I'm sure that you have many ways more, and I would like to read about them in the comments bellow.

As always, thanks for reading, and I hope you'd liked.

Posted on by:

michaeljota profile

Michael De Abreu

@michaeljota

Iā€™m a developer that do web applications by day, and games by night. I work with Typescript every day, using frameworks like Angular and Nest. Venezolano in the wild.

Discussion

markdown guide