Poisoning your Angular code: creating new Dom elements

Fermin Blanco
3 min readJul 18, 2020

I’ll be using @angular/material for the whole series.

Coming from an React Background you should find a lot of tentations making your Angular code feels like React, hopefully my mistakes would save you some time 😄.

Then let’s make one @Component,

Keep your eyes on,

todos.map( todo => <mat-grid-tile /> ... )

This should be get us back a list of <mat-grid-tile /> components but does it ?

Rendered

The answer is not of course but let’s find out why.

Angular uses component/template duality for building interfaces, component has the business rol and template the view, (this duality does not make much sense in React). The communications between them flows as following (Data binding),

  1. Interpolation
  2. Property Binding
  3. Event Biding

Interpolation the form we are using in our template has some(a lot) limitations about what can we do on them. Everything inside interpolation delimiters ({{ … }}) has to be a valid template expression.

Interpolation allows you to incorporate calculated strings into the text between HTML element tags and within attribute assignments. Template expressions are what you use to calculate those strings

Template expressions

Angular will convert everything inside double curly braces into a calculate string. Besides it comes with some rules that makes our React intentions to vanish.

A function call inside Angular templates will hurt our applications performance

todos.map( todo => <element />)

The thing with our expression is that we are attempting to manipulate the DOM in order to create new elements (side effect) inside it but this is not allowed in such a context.

besides Angular has no idea how to turn the mapping array into a string. Then it will take literally that tokens as text (and not as javascript syntax).

Then how can we achieve our desired behaviour? 😱

Structural directives

Angular framework comes with a construct called structural directives which allow us to perform changes to the DOM in a safe and clean way.

*ngFor structural directive

So we came with the standar/approved/right solution for this case, but let’s have a little fun and poison our code 😈👿.

The following has sensitive code that could hurt your eyes, if you decide to continue it could experience some damage on your brain (Non responsibility taken).

Map pipe

But what about if we could create a Map pipe that could make the transformations and returning back to us the resulting component. Is that even possible?

https://gist.github.com/luillyfe/3d572e99d8cbb8f751ea3aa235683d51

It turns out it does not work at all.

Map pipe render screen

Instead we are getting back a whole component text definition multiple by the number of item we have in our array. The reason why is pretty clear if you had have read the documentation before try such a madness code.

Use pipes to transform and format strings, currency amounts, dates, and other display data

Angular does not allow us to create new Dom elements from a Pipe.

--

--