primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.58k stars 4.61k forks source link

p-dropdown in angular 17 hangs loading for ever. #14407

Closed JimmyBjorklund closed 10 months ago

JimmyBjorklund commented 11 months ago

Describe the bug

I have a page with this code and its bin working fine in angular 16 but after the upgrade to 17 it hangs the load of the page for ever.

      <p-dropdown
          [options]="this.devices"
          [(ngModel)]="this.selected"
          optionLabel="name || deviceId"
          [filter]="true"
          filterBy="name,deviceId"
          placeholder="{{
            this.selected ? (this.selected.name ? this.selected.name + ' ( ' + this.selected.deviceId + ' )' : this.selected.deviceId) : tr('sensor.body.select')
          }}"
          (onChange)="this.selectedDevice($event.value.deviceId)"
          required="true"
          [style]="{ width: '100%' }"
          autoWidth="false"
          [ngModelOptions]="{ standalone: true }"
        >
          <ng-template pTemplate="this.selected">
            <div class="flex align-items-center" *ngIf="this.selected">
              <div>{{ this.selected.name || this.selected.deviceId }}</div>
            </div>
          </ng-template>
          <ng-template let-s pTemplate="item">
            <div class="flex align-items-center">
              <div>{{ s.name || s.deviceId }} {{ s.name ? "(" + s.deviceId + ")" : "" }}</div>
            </div>
          </ng-template>
        </p-dropdown>

Environment

"@angular/forms": "^17.0.7",
"@angular/google-maps": "^17.0.4",
"@angular/material": "^17.0.4",
"ng2-charts": "^5.0.3",
"primeng": "^17.1.0",
"zone.js": "^0.14.2"

"@angular-devkit/build-angular": "^17.0.7",
"@angular/cli": "^17.0.7",
"@angular/common": "^17.0.7",
"@angular/compiler": "^17.0.7",
"@angular/compiler-cli": "^17.0.7",
"@angular/core": "^17.0.7",
"@angular/platform-browser": "^17.0.7",
"@angular/platform-browser-dynamic": "^17.0.7",
"@angular/router": "^17.0.7",
"@auth0/angular-jwt": "^5.1.2",
"@ngneat/transloco": "^6.0.0",
"@types/node": "^20.10.5",
"rxjs": "~7.8.1",
"typescript": "^5.2.2"

Reproducer

No response

Angular version

17.0.7

PrimeNG version

17.1.0

Build / Runtime

TypeScript

Language

ES5

Node version (for AoT issues node --version)

v20.10.0

Browser(s)

Edge Version 120.0.2210.77 (Official build) (64-bit)

Steps to reproduce the behavior

No response

Expected behavior

No response

github-actions[bot] commented 11 months ago

We're unable to replicate your issue, if you are able to create a reproducer by using PrimeNG Issue Template or add details please edit this issue. This issue will be closed if no activities in 20 days.

JimmyBjorklund commented 11 months ago

https://stackblitz.com/edit/github-4z4rkv?file=src%2Fapp%2Fapp.component.ts If i remove the primeflex it stops working, much like my app but i i add flex to my project it still is broken. Might be some other depenacy that i am missing.

dbelob commented 11 months ago

@JimmyBjorklund Please fix string in app.component.html file (name of template):

instead of

<ng-template pTemplate="this.selected">

should be

<ng-template pTemplate="selectedItem">
dbelob commented 11 months ago

@cetincakiroglu See similar issue #14320

JimmyBjorklund commented 11 months ago

That fixes the initial load state when it works, but in my case it do not even load the page and i need to kill the browser compleatly as it hang the entire page.

cetincakiroglu commented 10 months ago

I don't see any issue in the example. Could not replicate the mentioned behavior. Could you please guide me how to reproduce it?

stefhorst commented 10 months ago

I have a similar issue, if I have a function returning my objects for the dropdown options. The browser is freezing because it recalls the method all the time in a loop. zone Version 0.14.4, e.g. [options]="getArray() | async "

Michiel-s commented 10 months ago

I also have this issue of the browser freezing upon template with <p-dropdown>

I'm using:

This code works:

import { Component } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options = [];
}

This code does NOT work

Notice the only difference is the .slice() method call on options

import { Component } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options.slice()"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options = [];
}
Michiel-s commented 10 months ago

@cetincakiroglu I tried to make the example as small as possible for you to be able to replicate the issue. Could you update the labels.

Michiel-s commented 10 months ago

Btw. notice that it is not the slice() function call from my example that is causing the issue, but like @stefhorst mentioned, the issue occurs when the options are return by a function.

E.g. the following code also produces the error:

import { Component } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options()"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options() {
    return [];
  }
}
cetincakiroglu commented 10 months ago
options

here it works https://stackblitz.com/edit/github-4z4rkv-mkxhp5?file=src%2Fapp%2Fapp.component.html

cetincakiroglu commented 10 months ago

I also have this issue of the browser freezing upon template with <p-dropdown>

I'm using:

  • Primeng v17.3.0
  • angular/core v17.0.8
  • angular/common v17.0.8
  • angular/forms v17.0.8
  • rxjs v7.8.1
  • zone.js v0.14.2

This code works:

import { Component } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options = [];
}

This code does NOT work

Notice the only difference is the .slice() method call on options

import { Component } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options.slice()"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options = [];
}

Correct usage as below:


<p-dropdown [options]="cities" [(ngModel)]="selectedCity" optionLabel="name" [showClear]="true" placeholder="Select a City"></p-dropdown>

options = [ { name: 'New York', code: 'NY' }, { name: 'Rome', code: 'RM' }, { name: 'London', code: 'LDN' }, { name: 'Istanbul', code: 'IST' }, { name: 'Paris', code: 'PRS' } ];

cities: any[];

ngOnInit(){
 this.cities = this.options.slice(0,1)
}
JimmyBjorklund commented 10 months ago

I can confirm that the issue i have is more or less the same if i have a private variable called devices and a property that return this.devices || [] then it hangs for ever but if i make the variable public then it works. Something is broken here.......

Michiel-s commented 10 months ago

@cetincakiroglu thanks for your reply. With this hint I managed to workaround.

I still don't understand why the correct usage is to "not use a function call" in the template as in my first example [options]=options(). In primeng v16 this worked fine.

For the issue with the slice() call I used the solution with ngOnInit you gave.

For another situation that gave the same issue I found a solution with the new Angular signals.

import { Component, Signal, computed } from '@angular/core';
import { DropdownModule } from 'primeng/dropdown';

@Component({
  selector: 'app-test-p-dropdown',
  standalone: true,
  imports: [DropdownModule],
  template: '<p-dropdown [options]="options()"></p-dropdown>',
  styles: '',
})
export class TestPDropdownComponent {
  options: Signal = computed(() => {
    return [];
  });
}

Still I think the issue reported here is a bug and that the issue should be reopened. But that is up to you.

Thank you for the reply.

pscanlon1 commented 10 months ago

How can this be closed? If you need to dynamically create a list of items at runtime, @cetincakiroglu this is still an issue.

stefhorst commented 10 months ago

@pscanlon1 your are right. it's a critical bug. Though it's not good practice to have functions as options, it's sometimes necessary, to use it especially with params. At the moment the dropdown is a critical component in primeng. please consider open it again @cetincakiroglu

pscanlon1 commented 10 months ago

@pscanlon1 your are right. it's a critical bug. Though it's not good practice to have functions as options, it's sometimes necessary, to use it especially with params. At the moment the dropdown is a critical component in primeng. please consider open it again @cetincakiroglu

It looks like _options in the angular 17 branch was changed from

_options: any[] | undefined;

to

_options = signal<any[] | undefined>(null);

pscanlon1 commented 10 months ago

I can confirm that the issue i have is more or less the same if i have a private variable called devices and a property that return this.devices || [] then it hangs for ever but if i make the variable public then it works. Something is broken here.......

+1

cetincakiroglu commented 10 months ago

How can this be closed? If you need to dynamically create a list of items at runtime, @cetincakiroglu this is still an issue.

Could you please share a stackblitz example so we can identify the issue?

nicobytes commented 2 months ago

@cetincakiroglu I have the same issue with slice.

It seems like an incompatibility between Angular's SlicePipe and PrimeNg v17

A general guess, SlicePipe is not a Pure Pipe and has Angular's own logic implemented inside that doesn't work like a native slice

Test the Slice pipe with PrimeNg v15 and v17

Screenshot 2024-09-10 at 4 29 03 PM