Tips for transferring information to various templates with *ngFor and *ngIf in Angular 4

I'm working with an object that looks like this

let obj = [{
    templateId: 1,
    name: "Template 1"
}, {
    templateId: 2,
    name: "Template 1"
}, {
    templateId: 3,
    name: "Template 1"
}];

Within my HTML Template, I'm attempting to pass data to different templates based on the templateId as shown below

<div *ngFor="let tmpl of obj">
    <div *ngIf="tmpl.templateId == 1; else templateTwo; context: tmpl">
        {{ tmpl.name }}
    </div>
</div>
<ng-template #templateTwo let-data="data">
    <div *ngIf="data.templateId == 2; else templateThree; context: data">
        {{ data.name }}
    </div>
</ng-template>
<ng-template #templateThree let-data="data">
    <div *ngIf="data.templateId == 3">
        {{ data.name }}
    </div>
</ng-template>

Even though I have structured my HTML template to pass data based on the templateId, I am facing errors in the code. Can you please guide me on what mistake I might be making here?

I would appreciate it if you could provide me with the correct approach.

Answer №1

If you want to pass your context to a specific template without changing your HTML structure, you can use the *ngTemplateOutlet directive on an ng-container element:

<div *ngFor="let tmpl of obj">

   <div *ngIf="tmpl.templateId == 1">
      {{ tmpl.name }}
   </div>

   <ng-container *ngTemplateOutlet="templateTwo; context: tmpl"></ng-container>
   <ng-container *ngTemplateOutlet="templateThree; context: tmpl"></ng-container>

</div>

<ng-template #templateTwo  let-id="templateId" let-name="name">
   <div *ngIf="id == 2">
        {{ name }}
   </div> 
</ng-template>

<ng-template #templateThree  let-id="templateId" let-name="name">
   <div *ngIf="id == 3">
        {{ name }}
   </div> 
</ng-template>

Check out an example code on stackblitz.com for reference.

Another approach is to include your ng-templates directly inside the div with ngFor and utilize the input variable declared in your ngFor statement:

<div *ngFor="let tmpl of obj">

    <div *ngIf="tmpl.templateId == 1; else templateTwo">
        {{ tmpl.name }}
    </div>

    <ng-template #templateTwo >
      <div *ngIf="tmpl.templateId == 2; else templateThree; ">
          {{ tmpl.name }}
      </div>
    </ng-template>

    <ng-template #templateThree >
        <div *ngIf="tmpl.templateId == 3">
            {{ tmpl.name }}
        </div>
    </ng-template>

  </div>

Answer №2

Assuming I have correctly understood your query and you prefer not to utilize ng-template, you can implement the following code instead:

<div *ngFor="let template of objects">

    <div *ngIf="template.id === 1">
        ...
    </div>

    <div *ngIf="template.id === 2">
        ...
    </div>

    <div *ngIf="template.id === 3">
        ...
    </div>

  </div>

Answer №3

If you happen to come across this in the future, I recommend solving it by utilizing ng-container along with an expression (assigned to *ngTemplateOutlet=) that determines the name of the ng-template to use for the current item in the array being looped through.

<ng-template #templateOne let-tmpl="tmp">
  <div>
    {{ tmpl.name }}
  </div>
</ng-template>

<ng-template #templateTwo let-data="tmp">head>
  <div>
    {{ data.name }}
  </div>
</ng-template>

<ng-template #templateThree let-data="tmp">
  <div>
    {{ data.name }}
  </div>
</ng-template>

<div *ngFor="let tmpl of obj">
  <ng-container *ngTemplateOutlet="tmpl.templateId == 1 ? templateOne :
    tmpl.templateId == 2 ? templateTwo : templateThree; context: {tmp: tmpl}"></ng-container>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps can I take to adapt my component in order to incorporate RxJs?

I am trying to gain proficiency in RxJs and, for educational purposes, I am interested in understanding how to modify the following code or if it is even feasible. Within my project, there is a component called MeetingObjectComponent which contains a chil ...

I'm confused as to why I keep receiving alert messages every time I click on a button. Can someone please provide

My aim is to enhance the functionality such that clicking the blue button changes the reading status to either <Yes> or <Not>. Any guidance on this would be greatly appreciated. Additionally, I am puzzled as to why, currently, I receive an aler ...

Issue with Angular 2 Http and RxJS: Undefined property 'unsubscribe' causing errors

UPDATE: Issue resolved! Check out my response below for potential help to others. If you have a better solution, feel free to share! :) Currently, I am developing an Angular 2 Universal API cache, and the ApiService setup is as follows: import {Http} from ...

Utilizing a single code base for both Web development with Angular 4 and Mobile app development with Ionic 3

I'm interested in finding out if I can utilize the same code base for both my Angular 4 web application and an Ionic 3 mobile application that I need to develop. As someone who is new to Ionic 3, I've been exploring the documentation and discove ...

Display HTML code within a data attribute

I have a function that modifies an element from OpenLayers. In the official documentation, it mentions that the property label accepts either HTML or a string. methods: { onUpdatePosition (coordinate) { this.deviceCoordinate = coordinat ...

Is the presence of a potential leak suggested by this arrangement in the heap snapshot retainer hierarchy

While analyzing a Heap snapshot, I came across a retainer hierarchy that looks like this: https://i.sstatic.net/Zg3bJ.png Is it possible that the MuiThemeProviderOld element (highlighted in yellow and from the @material-ui/core library) is causing a memo ...

Exploring the implementation of AES encryption and decryption functionality between Java and JavaScript

Currently, I am working on implementing an AES/CBC/PKCS5Padding algorithm. Initially, I used CryptoJS in JavaScript and was amazed by how smoothly encryption and decryption worked within seconds. Despite my efforts, I struggled to find a compatible solutio ...

Failing to locate module: Issue encountered after updating Angular to version 13 - Error: The package path ./locales is not being exported from

With the introduction of TypeScript 2.4, dynamic import() expressions were added to allow for the asynchronous loading and execution of ECMAScript modules on demand. I am currently facing an issue while trying to dynamically import the localization module ...

Is it possible to incorporate async await with SetState in React?

Is there a way to properly setState when needing async/await data inside it? I know it's not recommended, but I'm struggling with getting data before setting the state. Any suggestions? codesanbox: https://codesandbox.io/s/infallible-mendeleev-6 ...

IE encountered an invalid character

While working on a JavaScript function, I encountered an issue with a string variable. Specifically, when running the page in IE with this script, I receive an error message indicating an invalid character at the following line: let displayString = `${s ...

How can I extract an array of objects from an array of arrays containing objects?

Here is the array I am currently working with: let findAllSegmentProjectMediaFilesXref = [ { it: 0, bt: 0, items: [ { mute: false, startPosition: 10, endPosition: 20, ...

Deactivate particular months within the JqueryUI date picker

I'm currently working on a booking form that involves the jQuery UI Datepicker. I've encountered a major issue that I could use some assistance with: There are certain trips where only specific days are available for booking, and these trips can ...

Webstorm seems to be having trouble identifying Next.js

When I create a Next.js app using the command npx create-next-app my-app --use-npm Everything is successfully installed, but when using WebStorm, I noticed that it does not auto import the <Link> component from Next.js. I have to manually import it ...

Convert Binary Data to PDF Using Javascript Through Streaming

Upon requesting a Web-service, I received the following response (PDF file Streamed) %PDF-1.5 %µµµµ 1 0 obj <</Type/Catalog/Pages 2 0 R/Lang(en-GB) /StructTreeRoot 10 0 R/MarkInfo<</Marked true>>>> endobj 2 0 obj <</Type/ ...

Using the ngFor directive, parent and child components can establish communication even with empty arrays

I am working on passing data from a parent component to a child component using the ngFor directive. However, I am facing an issue when some arrays have no length, as I need to indicate to the child component that the array is empty. How can I achieve this ...

Dynamically adding a CSS gradient to an element with JQuery

Check out my HSL color picker on JS Bin I have created a simple HSL color picker that dynamically applies a gradient to a range input type upon DOM ready and changes to update the picker. // Code Update Setup $(".cpick-code-hsl").on('change keyup&ap ...

Tips for displaying a combobox popover from @reach/combobox within a MUI dialog element

I've been attempting to integrate a map from the Google Maps API and a combobox popover from @reach/combobox within a MUI dialog component. However, I've encountered an issue where the combobox popover isn't displaying. After some investigat ...

Screen out words from one string that appear in the other

Hello everyone, I am a beginner in JavaScript and I have a question about how to filter out two words from one string based on another string. string1 = ['mango', 'iPhone', 'banana', 'computer', 'apple', &a ...

offsetWidth varies across different browsers

There seems to be a 1px difference in the value of element.offsetWidth between Firefox and Chrome. I have been researching this issue. I attempted to apply a CSS reset and moved the element further away from the screen borders (as older versions of IE wer ...

Querying MongoDB using JavaScript function

Currently, I am utilizing a MongoDB query within a JavaScript function. The script is structured as follows: var continous = ['b', 'e', 'LBE']; continous.forEach(e => izracun(e)); function izracun(atr) { var query1 = ...