Teleport Content Anywhere In Angular Applications

Nivrith
Evergreen Engineer
Published in
3 min readMay 28, 2022

Sometimes you need to break the top-down content projection model in Angular and have the ability to project some Content DOM laterally to sibling component sub trees.

If you’ve ever been in a position where you needed to show different buttons on a toolbar or sidebar based on a different route, but your binding logic was in a child or sibling component, then you understand the pain.

Let me introduce 🎉🎉🎉 NGX-TELEPORT 🎉 🎉 🎉

🚀 Declarative · 🎉 Very Simple to use · 🍻 No Auxilary Routing ·
💚 No Imperative Portal Creation and Lifecycle Management

It’s super simple to use, with only two building blocks :

  1. Wrap the content you want to teleport in <ngx-teleport to="milkyway"></ngx-teleport> tags
  2. Add <ngx-teleport-outlet name="milkyway"></ngx-teleport-outlet> to any component template where you want to teleport your content

This is especially useful where you have a top-level Application Shell with a sidebar, toolbar, menu etc and you would like to show different content in let’s say the toolbar.

ngx-teleport lets us achieve this by using a declarative content projection approach. We no longer need to worry about the complexities of route paths and the binding indirection of auxiliary routing. ngx-teleport simplifies this issue by keeping the teleported templates’ binding logic in the context of the component where its input and output binding occurs (just like a regular angular component template 🎉).

<!-- ComponentA -->
<ngx-teleport to="sidebar">

<p *ngIf="someExpressionInComponentAScope">
I am a paragraph
</p>

<some-component [color]="somePropertyInComponentA" >
</some-component>
<button (click)="someMethodInComponentA($event)"></button></ngx-teleport>

We also don’t need to worry about imperative lifecycle management of Portals because this is handled out of the box ngrx-teleport.

<!-- ComponentA --><!-- I will render when [ngIf] is truthy -->
<ngx-teleport *ngIf="expressionInComponentAScope" to="sidebar">

<p>I will be destroyed when ComponentA is destroyed</p>
</ngx-teleport>

That being said, auxiliary routing and Portals have their own place and use cases. Remember, every solution solves a specific set of problems efficiently. It is our job to choose the right tools for the right task. We are just expanding our tool arsenal!

Combining with Content Projection

You can take things to the next level by combining this with regular content projection, auxiliary binding or Portals!

I will show you how you can combine ngx-teleport with content projection. The other two can be your homework 😉

Let us assume that we have a toolbar component that expects toolbar items to be projected in.

<!-- ToolbarComponent -->...
<ng-content select="app-toolbar-item"></ng-content>
...

And let’s assume we have used the toolbar somewhere in our top-level application layout.

<!-- AppComponent --><header>  <app-toolbar>

<app-toolbar-item>...<app-toolbar-item>
<app-toolbar-item>...<app-toolbar-item>
<app-toolbar-item>...<app-toolbar-item>
<app-toolbar-item>...<app-toolbar-item>
<!-- Context bound toolbar items will be teleported here -->
<ngx-teleport-outlet name="toolbar">
</ngx-teleport-outlet>
<!--Teleported Content Will Render Here -->
</app-toolbar></header><main>
...
<router-outlet></router-outlet>
...
</main>

Notice how the teleported content renders adjacent to and not wrapped inside the ngx-teleport-outlet tags? The <router-outlet> works in a similar way. This hurts my eyes too but the library does this to take advantage of composition in content projection.

<!-- ComponentB somewhere down the app's component tree -->
...
<ngx-teleport to="toolbar">

<!-- This will be transported to toolbar and projected in -->
<app-toolbar-item (click)="someMethodInComponentB">
Do Something that makes sense only in component B's context
</app-toolbar-item>
</ngx-teleport>

...

Imagine all the possibilities.

Installation

Install easily using npm

npm install ngx-teleport

or using yarn

yarn add ngx-teleport
  • Just addNgxTeleportModule in the imports array of NgModule decorator of whichever components you are using ngx-teleport and ngx-teleport-outlet in

Here is a simple StackBlitz to see it in action:

Happy Engineering!

If you’d like to be updated about more articles like this subscribe to my free newsletter

--

--

Nivrith
Evergreen Engineer

Software Engineer living a polymath lifestyle in Adelaide, Australia