Using the *ngFor directive within an <ng-container> element and wrapping it in an <ng-template> is a great way to dynamically display various data in

I have encountered an issue with my HTML file. The initial content within the ng-container tag is displaying data correctly. However, upon clicking the button to open the details panel, which utilizes the ng-template, only the first data entry from the array is being rendered. It seems like there might be a need to dynamically generate the template, but I am unsure about how to proceed in order to resolve this problem.

 <ng-container *ngFor="let member of members; trackBy: trackByFn;">
    <div class="flex flex-col py-4 sm:flex-row sm:items-center">

        <div class="flex items-center">

            <!-- Info details panel button -->
            <ng-container *ngIf="members?.length">
                <button class="w-5 h-5 ml-1 min-h-5"
                    [disabled]="member.session.length === 0"
                    mat-icon-button
                    (click)="openInfoDetailsPanel()"
                    #infoDetailsPanelOrigin>
                    <mat-icon
                        [ngClass]="{
                            'text-gray-400 icon-size-8': member.session.length === 0,
                            'text-green-600 icon-size-8': member.session.length > 0
                        }"
                        [svgIcon]="'cast_connected'">
                    </mat-icon>
                </button>
            </ng-container>
            <!-- Info details panel -->
            <ng-template #infoDetailsPanel>
                <div class="flex flex-col py-4 px-6 w-full max-w-160 space-y-1.5 border text-md rounded shadow-md overflow-auto bg-card">
                    <div class="flex">
                        <span>{{member | json}}</span>
                        <span>{{member.session | json}}</span>
                        <ng-container *ngFor="let item of member.session">
                            <tr>
                                <td  class="px-2 ">{{item.ip}}</td>
                                <td  class="px-2 ">{{convertDateTimeToLocaleDate(item.registrationDate)}}</td>
                                <td  class="px-2 ">{{convertDateTimeToLocaleTime(item.registrationDate)}}</td>
                            </tr>
                        </ng-container>
                    </div>
                </div>
            </ng-template>
        </div>
    </div>
</ng-container>

Within the TypeScript file, we have the following function:

@ViewChild('infoDetailsPanelOrigin') private _infoDetailsPanelOrigin: MatButton;
@ViewChild('infoDetailsPanel') private _infoDetailsPanel: TemplateRef<any>;

The function is as follows:

openInfoDetailsPanel(): void
    {
        // Create the overlay
        this._overlayRef = this._overlay.create({
            backdropClass   : '',
            hasBackdrop     : true,
            scrollStrategy  : this._overlay.scrollStrategies.block(),
            positionStrategy: this._overlay.position()
                                .flexibleConnectedTo(this._infoDetailsPanelOrigin._elementRef.nativeElement)
                                .withFlexibleDimensions(true)
                                .withViewportMargin(16)
                                .withLockedPosition(true)
                                .withPositions([
                                    {
                                        originX : 'start',
                                        originY : 'bottom',
                                        overlayX: 'start',
                                        overlayY: 'top'
                                    },
                                    {
                                        originX : 'start',
                                        originY : 'top',
                                        overlayX: 'start',
                                        overlayY: 'bottom'
                                    },
                                    {
                                        originX : 'end',
                                        originY : 'bottom',
                                        overlayX: 'end',
                                        overlayY: 'top'
                                    },
                                    {
                                        originX : 'end',
                                        originY : 'top',
                                        overlayX: 'end',
                                        overlayY: 'bottom'
                                    }
                                ])
        });

        // Create a portal from the template
        const templatePortal = new TemplatePortal(this._infoDetailsPanel, this._viewContainerRef);

        // Attach the portal to the overlay
        this._overlayRef.attach(templatePortal);

        // Subscribe to the backdrop click
        this._overlayRef.backdropClick().subscribe(() => {

            // If overlay exists and attached...
            if ( this._overlayRef && this._overlayRef.hasAttached() )
            {
                // Detach it
                this._overlayRef.detach();
            }

            // If template portal exists and attached...
            if ( templatePortal && templatePortal.isAttached )
            {
                // Detach it
                templatePortal.detach();
            }
        });
    }

Answer №1

When you create the templatePortal, the variables in your .ts file become accessible.

In addition, you have the ability to pass data as shown here

const data={prop1:'',prop2:''}
const templatePortal = new TemplatePortal(
        this._infoDetailsPanel, 
        this._viewContainerRef,
        {
           $implicit: data
        });

If you use the following code in your template:

 <ng-template #infoDetailsPanel let-data>
   You can access:
      {{data.prop1}} {{data.prop2}}
 </ng-template>

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

Issues with extensions during the Angular 9 Ivy compilation process

Good day! After upgrading a v8 project to v9, I encountered some errors related to extensions in the compiler. These errors are not present in another project that I also recently upgraded. The extensions, which are basic for constructors and prototypes, ...

Exploring Google Places with Angular 2, Typescript, and Ionic 2

Has anyone successfully transformed this code into TypeScript? var map; var infowindow; function initMap() { var pyrmont = {lat: -33.867, lng: 151.195}; map = new google.maps.Map(document.getElementById('map'), { center: py ...

Why is the variable suddenly a number when I clearly defined it as a string?

Let's start with the following code snippet: let vAny: any = 10 let s1: string = vAny; console.log(typeof s1) In this scenario, I have explicitly defined that s1 should be a string. However, when inspecting the type of s1, it shows up as a number in ...

The value is currently unset in the TypeScript language

The variable `this.engenes_comparte` is showing up as undefined inside the subscribe function, but it works fine outside of it. baja(){ this._restService.getEngines(this._globalService.currentFisherMan.nid).subscribe((data : any[]) => { le ...

Utilize string generic limitations as dynamically generated key

I am looking to create a type that can accept a string value as a generic argument and use it to define a key on the type. For example: const foo: MyType<'hello'> = { hello: "Goodbye", // this key is required bar: 2 } I attempted to ...

How to position Angular Component at the bottom of the page

I have been working on my angular application and recently created a footer component that I want to stay at the bottom of the page like a typical footer. The footer component is included in the default app.component.html file, which makes it visible on th ...

Setting up the Angular JS environment manually, without relying on an Integrated

I am a complete beginner when it comes to Angular JS. I recently inherited an Angular JS application that I need to run on a server without using any Integrated Development Environment (IDE). I have tried researching online for methods to run the applicat ...

In DynamoDB, when using Number in KeyConditionExpression, it is interpreted as a Map which can lead to unexpected

Setting In my TypeScript CDK project, I am dealing with the QueryInput-Object. The code snippet below shows how it's being used: const params: QueryInput = { TableName: criticalMessagesTableName, ProjectionExpression: 'message', ...

Using Typescript to automatically infer strongly-typed recursive index types

Commencing with an Animal interface and a detailed map of animals residing on my farm: export interface Animal { species: string; edible: boolean; } export interface FarmMap{ [key: string]: Animal; } Everything seems to be running smoothly. Here ...

Caution: The `id` property did not match. Server: "fc-dom-171" Client: "fc-dom-2" while utilizing FullCalendar in a Next.js environment

Issue Background In my current project, I am utilizing FullCalendar v5.11.0, NextJS v12.0.7, React v17.0.2, and Typescript v4.3.5. To set up a basic calendar based on the FullCalendar documentation, I created a component called Calendar. Inside this comp ...

Save JSON Tree data in the Database

Given a tree structure JSON, I am tasked with creating an API to insert all the data into a database at once. The organization entities can have multiple parents and children relationships. An example of the JSON data: { "org_name": "orga ...

What is the proper way to address the error message regarding requestAnimationFrame exceeding the permitted time limit?

My Angular application is quite complex and relies heavily on pure cesium. Upon startup, I am encountering numerous warnings such as: Violation ‘requestAnimationFrame’ handler took 742ms. Violation ‘load’ handler took 80ms. I attempted to resolve ...

Tips for enabling custom tags in the tinyMce editor

<textarea><div style="margin-top: 15px;"> <div class="dropdown "> <p> hello my name is <Enter Your Name> </p> <p> hehe</p> </div> </div> ...

What is the best method for launching a Node.js (Express) app on a live server automatically?

My Angular app relies on an express backend. What is the best way to deploy this application on a remote server so that it always runs smoothly? ...

Expanding the Mat Expansion Panel in AngularKeep your Mat Expansion Panel

Within my Angular 6 project, I have a situation where a mat-expansion-panel is nested within a mat-accordion. This particular mat-expansion-panel is dynamically connected to an array called moves, which controls its content. Here's how it looks: < ...

Tips on transferring key values when inputText changes in ReactJs using TypeScript

I have implemented a switch case for comparing object keys with strings in the following code snippet: import { TextField, Button } from "@material-ui/core"; import React, { Component, ReactNode } from "react"; import classes from "./Contact.module.scss" ...

How to make Angular resolver and component share an injected service?

In my products list component, I have a table displaying various products. Since there is a considerable amount of data, I implemented a resolver to prevent the user from being directed to the page until all the data is loaded. The resolver currently utili ...

The function signature `(err: any) => void` does not share any properties with the `QueryOptions` type on the Node route

I'm encountering an issue with a route in my Node controller that is causing errors and preventing Node from running properly public async deletePost(req: Request, res: Response) { const { id } = req.params; const deletedPost = await BlogPostM ...

Component html element in Angular not being updated by service

Within my Angular service, I have a property linked to a text field in a component's HTML. Oddly, when this property is updated by the service, the new value doesn't reflect in the HTML element unless the element is clicked on. I'm perplex ...

Exploring the wonders of using the Async Pipe with Reactive Extensions

I'm facing a little issue with the async pipe in Angular. Here's my scenario: I need to execute nested observables using the async pipe in HTML because I'm utilizing the on-push change detection strategy and would like to avoid workarounds ...