Splitting Data and Presentation Components in Angular

Felipe Gonçalves Marques
TaqtileBR
Published in
3 min readJun 11, 2018
Photo by Dmitri Popov on Unsplash

Split the logic of fetching data from how it is presented is a great step towards separation of concerns. It gives us flexibility to change any of those parts without breaking the other, as long as they respect their interfaces.

Also, sometimes this splitting is what we need to reduce that big classes that represents a screen.

For example, suppose we have an user registration form and it has an Autocomplete field that looks for Star Wars characters to be selected. The user can choose as many as he wants. Besides that, the form also has other fields as Name, Email, Telephone, etc. We can also add some conditional fields: if the user is a student, we ask for the university otherwise, we can ask for the company.

The Component representing this form might become really big and any reduction, respecting good practices, is an improvement.

Supposing we add all the dynamic part of the autocomplete in the Component, we would have something like this (you can also check the stackblitz):

The data and presentation are separated here, because the presentation is done by the Autocomplete component. But every time we would like to use the Star Wars Characters Autocomplete, we would have to reimplement the event listeners, the call to the service, the unsubscribe, etc. This can become very repetitive and error prone. So we build a component that handles this!

The solution here is inspired in Isaac Mann article about the Angular equivalent of React renderProps pattern.

We will build a component that provides the autocomplete with the options and the callbacks through a context object.

This component is called StarWarsCharactersAutocomplete. Its HTML would look like this:

Here we use ngTemplateOutlet. It allows us to render a TemplateRef providing some context to it. So, the layoutTemplate here can access the variables that are in the context object. In this case we have the options and the search callback. This directive would be used as:

Here, we get the two variables we need to bind to the component. Finally, let's see how the component works:

Here we use ContentChild to find the TemplateRef that we will pass to the ngTemplateRouterOutlet. We also define the variables for the context object and, finally, bind the changes to calls to the Star Wars Service.

This way we can reduce the AppComponent:

We have isolated both the data fetch service and the autocomplete component. As a result we have much simpler, flexible and reusable components!

Compared to the React implementation of this pattern, the Angular equivalent has some boilerplate and is not very clear how it works. But it is better then polluting other classes with this logic every time we want to add an autocomplete with this data.

Finally, I think it is possible to simplify this with just a structural directive, although this is not the common usage of this directives as Angular suggest.

You can check the final code here.

The ideas here are also inspired by Dan Abramov Presentational and Container Components.

This is my first medium article! :)

If you have any suggestions or questions, please let me know!

--

--