Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using even and odd with Angular *ngFor

Tags:

angular

I have a list of records which I want to display using a table and ngFor. To avoid using pagination, I'd like to show 2 records per table row, something like this:

enter image description here

As you can see, I'd like to show the even records on the left columns of the table and the odd records on the right side. I tried to implement this idea into my Angular application using the following template code, but the compiler complains it:

<div class="col-12">        
    <table class="table table-hover table-sm">
        <thead>
            <tr class="text-center">
                <th scope="col">Time</th>                       
                <th scope="col">User</th>
                <th scope="col">Hostname</th>
                <th><!-- SEPARATOR --></th>
                <th scope="col">Time</th>                       
                <th scope="col">User</th>
                <th scope="col">Hostname</th>
            </tr>
        </thead>
        <tbody>
            <ng-container *ngFor="let event of formModel.controls['events']?.controls; 
                let i = index; 
                let even = even"
                [formGroupName]="i">
                <ng-container *ngIf="even; else dataOnTheRight">
                    <tr> <!-- START THE ROW FOR EVEN RECORDS -->
                </ng-container>
                <ng-container #dataOnTheRight>
                    <td> <!-- ADD SEPARATOR CELL FOR ODD RECORDS --> </td>
                </ng-container>

                <td class="align-middle">
                    {{ event.get('time').value  }}
                </td>
                <td>{{ event.get('username') }}</td>
                <td>{{ event.get('hostname') }}</td>

                <ng-container *ngIf="!even">
                    </tr> <!-- CLOSE THE ROW FOR ODD RECORDS -->
                </ng-container>
            </ng-container>
        </tbody>
    </table>
</div>

This is the error the compiler throws:

Compiler error

If this is not possible, I'll duplicate the table so I have one for the even records and another one for the odd, but I was wondering if there are some templating 'tricks' that allow me to do something like the code above.

Thanks!

like image 959
Fel Avatar asked Feb 19 '26 00:02

Fel


2 Answers

The problem is that if you recieve an even number of rows the last closing </tr> tag never gets printed so it puts a </tbody> after an <tr>. I think you could use last

            <ng-container *ngFor="let event of formModel.controls['events']?.controls; let i = index; let even = even; last as isLast"
            [formGroupName]="i">
            <ng-container *ngIf="even; else dataOnTheRight">
                <tr> <!-- START THE ROW FOR EVEN RECORDS -->
            </ng-container>
            <ng-container #dataOnTheRight>
                <td> <!-- ADD SEPARATOR CELL FOR ODD RECORDS --> </td>
            </ng-container>

            <td class="align-middle">
                {{ event.get('time').value  }}
            </td>
            <td>{{ event.get('username') }}</td>
            <td>{{ event.get('hostname') }}</td>

            <ng-container *ngIf="!even || isLast">
                </tr> <!-- CLOSE THE ROW FOR ODD RECORDS -->
            </ng-container>
        </ng-container>
like image 96
Sjoerd de Wit Avatar answered Feb 20 '26 15:02

Sjoerd de Wit


Angular says that you do not have </tr> tag in your row, so you have parsing error. It means that Angular starts to draw your row, however, *ngIf="!even" does not allow to insert </tr> tag at the current row. So you have the following HTML:

<tr> <td>1<td> ... <!-- this row is not even, so you do not have </tr> tag
                        and you get your error-->

What you can do is just show even rows and insert items from the odd row into even row:

<ng-container 
    *ngFor="let event of formModel.controls['events']?.controls; 
    let i = index; 
    let even = even"
    [formGroupName]="i">
    <ng-container *ngIf="even;">
       <tr>
            <td>{{item}}</td> 
            <td> <!-- ADD SEPARATOR CELL FOR ODD RECORDS --> </td>
            <ng-container *ngFor="let item of formModel.controls['events']?.controls[ i + 1]" >
                <td>{{ item }}</td>
            </ng-container>
       </tr>
    </ng-container>
</ng-container>
like image 45
StepUp Avatar answered Feb 20 '26 17:02

StepUp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!