Level 1: Angular 5+ Gotchas

2 minute read

At work, we’re architecting the future path of our front-end stack. A few months ago, we decided on Angular after running POCs against React, Vue, and Angular itself. There are a few reasons why we ended up where we did, but everyone’s entitled to their own opinions.

While working on Angular, I discovered a few gotchas that I thought deserved some special attention. This post is a collection of my findings.

Constructor vs. ngOnInit

On the surface, they do the same thing.

constructor(private todoHTTPService: TodoHTTPService) { 
    this.todoHTTPService.getTodos().subscribe((todos: Array<TodoJSON>) => { 
      this.todoJSON = todos; 
      todos.forEach(todo => this.transformedTodo.push(new TodoTitleStatus(todo.userId, todo.id, todo.title, todo.completed))); 
    });
}

has the same end result as

ngOnInit() { 
    this.todoHTTPService.getTodos().subscribe((todos: Array<TodoJSON>) => { 
      this.todoJSON = todos; 
      todos.forEach(todo => this.transformedTodo.push(new TodoTitleStatus(todo.userId, todo.id, todo.title, todo.completed))); 
    });
}

Constructor is a typescript concept and, from a Java background, is meant for what is required to even instantiate the class.

ngOnInit is Angular, and is called when Angular has finished constructing the component. It is called after the first ngOnChanges().

StackOverflow

Generally, we try to keep the constructor as light as possible. It’s a pain to set up tests for it and although I prefer to be as light on the Angular framework as possible, it doesn’t seem right in this case.

All the initialization logic should go in the ngOnInit and only the dependency injection for the constructor.

Class vs. Interface for Model definitions

In order to have well-ordered structure in your application, a good data model is essential. Without one, you’re just playing in the sand with all the JSON like in angular.js. Lel (at least the way that we do it at work).

In terms of performance, both are lightweight. My understanding is that both classes and interfaces are able to shape JSON data into the model objects that we want them to be in. That being said, interfaces are removed from compilation while classes remain. If you have methods and/or private variables, use classes. If not, and if all you really need is to shape the data, interfaces are fine.

Github

Addendum

I also decided to include some notes that I took from reading the Angular 2+ style guide below. Hope it may help distill some of the information even further.

Shared Module (Content that is repeated but not singletons)

For content that is referenced across the entire application.

  • Avoid putting services under shared unless intended to be singletons.
  • Mainly for components, directives, and pipes.

Core Module (Singleton content)

Singleton content shared across the entire application

  • Navigation/Spinner/Dialog Components
  • Logger and Exception Services

Lazy Loaded Modules

  • Don’t directly import lazy loaded modules, it defeats the purpose.

Components

  • Leave for only view logic and externalize the service for more complex logic.
  • Avoid calculations in the template but rather in the component itself.
  • Does not care how it gets the data, just that it knows who to ask for it.

Directives

Presentation logic without a template.

  • Use @HostBinding and @HostListener over host property.

Services

Singletons.

  • Single Responsibility Principle.
  • Inherited by children components when put in provider of parent.
  • For sharing state/methods between components.
  • @Injectable
  • Have data services.

Categories:

Updated: