Widgets and Components for Angular 2 and up

Michael De Abreu - Mar 10 '17 - - Dev Community

Intro

If you are comming from React, the React community as develop some patterns that made easy and simple to develop apps with this framework. One of this patterns is the smart and dumb component, or container and component. This keeps a separation between how a component should display the data, and how a component actually manage the data. If you want more about this, there are plenty of articles about it, this is not what I'm writing about.

Situation

The actual name for a piece of web page according to the standard it's "web component", so one might think that calling component to the piece of code that shows the data it's the most accurate way to name them. But...

I reject nature

Angular community had develop their own way of thinking about what a component is, and in the Angular community I had see so many times that a component have a behavior.

What?! This is just insane. A component should concern only about how to display the data, no how to manage it.

Well, it is true. The only fact that Angular components are called Components it's one of the examples to show my point of view. Still, we need some way to manage the display of the data.

Solution proposal

I know this would be only another solution proposal, and mine doesn't actually adds anything to current implementation, it's just syntactic sugar for the same thing.

Introducing Widgets

So... Widgets? What should they be? I propose Widgets to name anything that only should concern about how to display something. And this it's something that Angular it's great at, separation. I'm not saying that React it's bad about it, but I think that the Angular team had a better approach to this issue.

Ideally a Widget should have only @inputs and @outputs. That's all. A Widget had to be made to show info, and it have to be a component that reflects that in their code. There should be no logic inside a Widget, but the logic that a Widget need to show the data that is being inputed.

I also think about the way that the data should be managed inside the Widget, but that would be for another day (Or you can read this issue)

What widgets should be

  • Widgets should be the presentation components of and Angular application.
  • Widgets should be logicless.
  • Widgets should be concern about the style of their own data.

Questions

Widgets are just components?

Yes. :). No more, not less. Just components. They have to show information, but they should not care about how the information it's being provide for them.

Why another name then?

As I said, component in Angular community had been used for development of piece of web pages that manage information.

Why called them widgets?

Cause, after all, widgets actually are made to show information, so it's seems logical to call them that way.

Examples

There should not be one motivation for use a name proposal without an example, and that's what I'm going to give you.

import { Component, Input } from '@angular/core';

import { ITodoItem } from './../../models';

@Component({
  selector: 'my-todo-list-widget',
  template: `
  <ul>
    <my-todo *ngFor="let todo of todoList;trackBy:todo?.id"
      [todo]="todo"
    ></my-todo>
  </ul>
  `,
})
export class TodoListWidget {
  @Input() public todoList: ITodoItem[];
}
Enter fullscreen mode Exit fullscreen mode

This is a simple case of use. I'll try to explain the code.

import { Component, Input } from '@angular/core';

import { ITodoItem } from './../../models';
Enter fullscreen mode Exit fullscreen mode

First of all, imports. From @angular/core we import input and component decorators. Remember, everything in Angular it's a decorator, so are Widgets, that name it's just sugar. There is not a Widget decorator, and I don't think that it should be one. From a model folder, the import of the Item model.

@Component({
  selector: 'my-todo-list-widget',
  template: `
  <ul>
    <my-todo *ngFor="let todo of todoList;trackBy:todo?.id"
      [todo]="todo"
    ></my-todo>
  </ul>
  `,
})
Enter fullscreen mode Exit fullscreen mode

So we decorate. I use the suffix widget for the selector, cause I had a component with the same name. So if you can name things better than I do, you should not need that. Also, the template, the less, the better. I think that if your template it's less than 10 lines, you should inline it. But, it's up to you. What is important it's to define all the display behavior here.

export class TodoListWidget {
  @Input() public todoList: ITodoItem[];
}
Enter fullscreen mode Exit fullscreen mode

Finally, we declare the class. This is the important part. As you can see, there is not logic here. It's just a class requesting an input property and nothing else.

More examples

If you want a couple of more examples about Widgets, checkout my repo angular2-ultimate-starter. This is based of AngularClass starter, but I added ngrx/store implementation, and a couple patters borrow from React, as Widgets.

Thanks you

This is all for now. This is my first post, like ever, about Angular. I hope you enjoy this, and for anything you have to say about this, I'm looking forward to read your comments. Cheers and happy coding!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .