Angular:Easy trick to pass dynamic data to a nested/child <ng-template> without using ngTemplateOutlet

Angular&NodeEnthusiast
Geek Culture
Published in
3 min readApr 17, 2022

I have seen this question across multiple platforms from many web developers. How to pass data to an <ng-template> which is nested inside another <ng-template> or another tag?

The answer to this question would be quite simple if I was able to use ngTemplateOutlet and ngTemplateOutletContext. But do all scenarios require these 2 properties? Not really. So what do you do then?

I came across a situation in my work project, where I had to construct a table and few columns in that table had to be rendered different from the others. When I say “different” I mean that those columns either required the usage of buttons OR needed pipes to format the data etc. It wasn’t simple rendering of data. I resorted to using <ng-template> to solve this problem.

I have recreated this scenario with the table below containing data of 10 users. I have used buttons for the ToDos column, Pipe formatting for the Date Of Birth column and used a mailto link for the Email column. The remaining columns just render the text as it is.

The User data isn’t of great importance here. But just to give an idea,below is the structure of the first user object.

{
id: 1,
name: ‘Leanne Graham’,
username: ‘Bret’,
email: ‘Sincere@april.biz’,
dob: ‘11/22/1988’,
address: {
street: ‘Kulas Light’,
suite: ‘Apt. 556’,
city: ‘Gwenborough’,
zipcode: ‘92998–3874’,
geo: {
lat: ‘-37.3159’,
lng: ‘81.1496’,
},
},
phone: ‘1–770–736–8031 x56442’,
website: ‘hildegard.org’,
company: {
name: ‘Romaguera-Crona’,
catchPhrase: ‘Multi-layered client-server neural-net’,
bs: ‘harness real-time e-markets’,
},
},

AppComponent Class:

tableHeaders contains the list of headers to be displayed in the table. tableBody contains the list of properties that we shall access from the JSON to display the values in the table.

This kind of approach is helpful if you have multiple tables with the same columns but different data.

In the ngOnInit(), we are iterating through the users variable containing the Users data. We really don’t need all the properties in each object. The purpose of the iteration is to pick up the properties we need for the table, add it to an object obj and then push this object obj into a new property usersList.

usersList is the final array that will be used in the table.

The view() executes, when we click on the View ToDos button in the ToDos column of the table. The purpose of adding this method is just to show that user data can be accessed in the class from the <ng-template>.

AppComponent Template:

We have constructed the table headers by iterating through the tableHeaders property.

<tr> <th *ngFor=”let header of tableHeaders”>{{ header }}</th> </tr>

To construct the table body, we are iterating through the usersList array and within each iteration, we are iterating through the tableBody array. We are using a template with reference special for the email, todos and dob properties(corresponding to Email, ToDos and Date Of Birth column)and template with reference regular for other properties(corresponding to other columns).

<tr *ngFor=”let user of usersList”> 
<td *ngFor=”let option of tableBody”>
<span *ngIf=” ![‘email’, ‘todos’, ‘dob’].includes(option); then regular; else special “ >
</span>
<!---the templates are placed here--><ng-template #special>
<ng-container [ngSwitch]="option">
<span *ngSwitchCase="'email'">
<a href="mailto:{{ user[option] }}">{{ user[option] }}</a> </span>
<span *ngSwitchCase="'dob'">
<label>{{ user[option] | date: 'dd-MM-YYYY' }}</label> </span>
<span *ngSwitchCase="'todos'">
<button class="btn btn-primary" (click)="view(user.id)"> View ToDos</button>
</span>
</ng-container>
</ng-template>
<ng-template #regular>
<label>{{ user[option] }}</label>
</ng-template>
</td>
</tr>

Please note the position of the <ng-template>. They are within the <td> tag, so that they are can access the user variable of the outer iteration and also the option variable of the inner iteration.

Similarly if the child <ng-template> is nested inside a parent <ng-template>, even then the child can easily access all the data passed to the parent <ng-template>.

You can check the entire working example below.

--

--

Angular&NodeEnthusiast
Geek Culture

Loves Angular and Node. I wish to target issues that front end developers struggle with the most.