Angular / Primeng filter request to REST backend leads to infinite loop

Discussão em 'Angular' iniciado por Martin, Fevereiro 19, 2025.

  1. Martin

    Martin Guest

    I use primeng table with big data. To handle that I send my filters to the REST backend and show the results in my table. But each filter action ends up in an loop.

    Here is my service:


    public getMovements(filters?: any): Observable<Movement[]> {

    let uri = this.baseUrl + '?q=' + encodeURIComponent(JSON.stringify(filters));
    return this.httpClient.get<Movement[]>(this.baseUrl, this.httpOptions).pipe(
    map((result: any) => {
    return result._embedded.movements;
    }));
    }

    And the component's html code. When I enter manufacturer_name and press enter to filter, the loop starts:


    <p-table #dt [value]="movements" [paginator]="true" [rows]="50" [showCurrentPageReport]="true" responsiveLayout="scroll" currentPageReportTemplate="Zeige {first} bis {last} von {totalRecords} Einträgen" [rowsPerPageOptions]="[10,25,50]" styleClass="p-datatable-striped"
    [rowHover]="true" (onFilter)="onFilter($event)" [globalFilterFields]="['inventory_category_name', 'manufacturer_name', 'inventory_no', 'user_display_name', 'inventory_status_name']">
    <ng-template pTemplate="caption">
    <div class="flex flex-wrap gap-2 align-items-center justify-content-between">
    <span class="p-input-icon-left w-full sm:w-20rem flex-order-1 sm:flex-order-0">
    <i class="pi pi-search"></i>
    <input pInputText type="text" (input)="onGlobalFilter(dt, $event)" placeholder="Globale Suche" class="w-full" />
    </span>
    <button [routerLink]="'/inventories/movements/edit'" pButton class="p-button-outlined w-full sm:w-auto flex-order-0 sm:flex-order-1" icon="pi pi-user-plus" label="Neu"></button>
    </div>
    </ng-template>
    <ng-template pTemplate="header">
    <tr>
    <th pSortableColumn="inventory_category_name">Movement
    <p-sortIcon field="inventory_category_name"></p-sortIcon>
    </th>
    <th pSortableColumn="manufacturer_name">Modell
    <p-sortIcon field="manufacturer_name"></p-sortIcon>
    </th>
    <th pSortableColumn="inventory_no">Inventar-Nr.
    <p-sortIcon field="inventory_no"></p-sortIcon>
    </th>
    <th pSortableColumn="user_display_name">Mitglied
    <p-sortIcon field="user_display_name"></p-sortIcon>
    </th>
    <th pSortableColumn="inventory_status_name">Status
    <p-sortIcon field="inventory_status_name"></p-sortIcon>
    </th>
    <th pSortableColumn="edit_time" class="text-right">Bearbeitung
    <p-sortIcon field="edit_time"></p-sortIcon>
    </th>

    </tr>
    <tr>
    <th>
    <p-columnFilter type="text" field="inventory_category_name"></p-columnFilter>
    </th>
    <th>
    <p-columnFilter type="text" field="manufacturer_name"></p-columnFilter>
    </th>
    <th>
    <p-columnFilter type="text" field="inventory_no"></p-columnFilter>
    </th>
    <th>
    <p-columnFilter type="text" field="user_display_name"></p-columnFilter>
    </th>
    <th>
    <p-columnFilter type="text" field="inventory_status_name"></p-columnFilter>
    </th>
    <th class="text-right">
    <p-columnFilter type="text" field="editor_display_name"></p-columnFilter>
    </th>

    </tr>
    </ng-template>
    <ng-template pTemplate="body" let-movement>

    <tr>
    <td>{{ movement.inventory_category_name }}</td>
    <td>{{ movement.manufacturer_name }} {{ movement.inventory_movement_name }}</td>
    <td>{{ movement.inventory_no }} {{ movement.inventory_name }}</td>
    <td>{{ movement.user_display_name }}</td>
    <td>{{ movement.inventory_status_name }}</td>
    <td class="text-right">{{ movement.editor_display_name }} {{ movement.edit_time | date: 'dd.MM.yyyy HH:mm'}}</td>

    </tr>


    </ng-template>
    </p-table>

    And the component's code itself:


    import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
    import { Table, TableFilterEvent} from 'primeng/table';
    import { Movement } from '../../../api/movement'
    import { MovementsService } from '../../../service/movements.service';
    import { ConfirmationService, MessageService } from 'primeng/api';
    import { ConfirmDialogModule } from 'primeng/confirmdialog';
    import { Subject, take } from 'rxjs';

    @Component({
    templateUrl: './movementslist.component.html',
    providers: [ConfirmationService, MessageService]
    })
    export class MovementsListComponent implements OnInit {

    movements: Movement[] = [];

    constructor(
    private movementsService: MovementsService,
    private router: Router,
    private messageService: MessageService,
    private confirmationService: ConfirmationService,
    ) { }

    ngOnInit() {

    }

    onSelect(inventory_movement_id?: number) {
    this.router.navigate(["/inventories/movements/edit", inventory_movement_id]);
    }

    onGlobalFilter(table: Table, event: Event) {
    //not impemented yet
    }

    onFilter(event: TableFilterEvent) {

    // Here is the loop section ...
    console.log("onFIlter....");

    this.movementsService.getMovements(event.filters).pipe(take(1)).subscribe(data => {
    this.movements = data;
    });
    }

    }

    I think the problem is related to the observer. I'm not too familiar with the observer-subscriber principle in Angular. I am grateful for any help.

    Continue reading...

Compartilhe esta Página