Search code examples
javascriptangulartailwind-elements

Tailwind Elements Select component not working with Angular *ngFor


Here is my codes for basic angular component where I'm using Tailwind Elemets CSS framework.

app.componenets.ts

import { Component, OnInit } from '@angular/core';
import { Select, Datepicker, Input, initTE } from "tw-elements";

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'test-tailwind-elements';

ngOnInit(): void {
    initTE({ Datepicker, Input, Select });
}

fruitsList: { name: string[] }[] = [
    {
    name: ['Mango', 'Papaya', 'Banana']
    },
    {
    name: ['Mango', 'Papaya', 'Banana']
    },
    {
    name: ['Mango', 'Papaya', 'Banana']
    }
]
}

app.component.html

<table>
    <tr>
        <th>Fruits</th>
    </tr>
    <!-- <tr *ngFor="let item of fruitsList;"> -->
    <tr>
        <td>
            <select data-te-select-init>
                <option value="1">Mango</option>
                <option value="2">Papaya</option>
                <option value="3">Banana</option>
            </select>
        </td>
    </tr>
</table>

The issue I'm facing at here is, if we don't use *ngFor with <tr> html tag then it render the output properly. But, the moment we use that along with *ngFor it don't render properly.

Here are some screenshots for reference

Select dropdown working enter image description here

Select dropdown not working enter image description here

I feel like with *ngFor when inside a loop it's creating the dropdown list somehow it's can't able to register the components with DOM. But, I can't able to understand how to fix this.

Need some help.


Solution

  • It's due to initialising the components in ngOnInit, before the selects are ready with data-te-select-init, so they never get initialised. Change to using AfterViewInit and it works fine.

    import { Component, AfterViewInit } from '@angular/core';
    import { Select, Datepicker, Input, initTE } from "tw-elements";
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent implements AfterViewInit {
      title = 'test-tailwind-elements';
    
      ngAfterViewInit() {
        initTE({ Datepicker, Input, Select });
      }
    
      fruitsList: { name: string[] }[] = [
        {
          name: ['Mango', 'Papaya', 'Banana']
        },
        {
          name: ['Mango', 'Papaya', 'Banana']
        },
        {
          name: ['Mango', 'Papaya', 'Banana']
        }
      ]
    }
    

    Here's a working version in a repo.