Winner's Excogitations

A chronicle of the thoughts, learning experiences, ideas and actions of a tech junkie, .NET, JS and Mobile dev, aspiring entrepreneur, devout Christian and travel enthusiast.

[HOW TO] Convert An Angular Component Into HTML

4 years ago ยท 3 minutes read

bolorundurowb_com/production/article/ueagtqakokx17xwxrbm7

Introduction

Before we dig into the technical, permit me to reminisce a little. My reason for starting this website and the associated blog was to share my learning experiences and thoughts. If there is anything I have learnt along my software development journey, it is that when you are dealing with mature technologies and frameworks, most questions have been asked, most bugs have been reported and fixes or workarounds have been detailed and a thousand and one blog posts and articles would have been written about every minutia.

That has been my experience working with C#, JavaScript and Angular, but on some rare occasion, you find yourself trying to accomplish some arcane task, do research and not find much to go on.

A situation quite like that is what led to this post. While working on the dimmer module on the Ngx Semantic project, I found that I needed to instantiate a defined component, set its inputs and then retrieve the generated HTML to manually insert into the DOM at my convenience. I was able to find a solution which is what I'd detail below.

Setup

Let's define a sample component that takes one input. This would be the component that we need to programmatically instantiate and render.

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

@Component({
  selector: 'app-sample',
  template: `<div>Hello world. {{input}}</div>`
})
export class SampleComponent {
  @Input() input: string;
}

NOTE: if you are running Angular 10 and above you do not need to add the SampleComponent to the entry components of your module.

Implementation

With that done, in the component or directive where you need to manually render the sample component, you would need to inject a number of dependencies via the constructor as shown:

import {ApplicationRef, ComponentFactoryResolver, ApplicationRef} from '@angular/core';
...
constructor(private factoryResolver: ComponentFactoryResolver, private injector: Injector,
            private applicationRef: ApplicationRef)  {
}

Let's define a function to actually do the manual component rendering. The function would be renderComponent(). I would add comments in the function implementation detailed below to explain each step:

private renderComponent() {
  // generate a factory that would help in creating our component
  const factory = this.factoryResolver.resolveComponentFactory(SampleComponent);

  // create an instance of the sample component
  const component = factory.create(this.injector);

  // since we need to modify inputs on the component, we extract the instance and make our changes
  component.instance.input = 'John';

  // we attach the component instance to the angular application reference
  // this step is necessary as it allows for our components view to be dirty-checked
  this.applicationRef.attachView(component.hostView);

  // the step we have been building to
  // we pull the rendered node from the components host view
  const renderedHtml = (component.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
}

The content in the renderedHtml variable is the HTML representation of the component with the provided inputs. For the example above, the HTML would look something like:

<div>Hello World. John</div>

Conclusion

That's about it, I stumbled onto a solution for a very niche problem and shared as I think it may be useful to someone else.

Till next time, happy coding.
Cheers!

Share on:
[HOW TO] Run A Geospatial Search With EF Core and Npgsql
A simple how-to around finding entities with points that fall within a set of coordinates.
[HOW TO] Add CORS Support to your Fastify app
Adding CORS support to your Fastify API
Winner-Timothy Bolorunduro
Winner-Timothy Bolorunduro is a senior .NET developer with over 6 years experience helping organizations and individuals build compelling, stable and scalable web applications. Having spent the last three years in a fast-paced startup environment working remotely, he understands what goes into being part of a team that produces value for clients.

Comments