0
votes

I just started using PrimeNG and I ran into some problem when using inputtext.

I have a datatable with single selection and when a row is selected, a dialog is opened. I'm trying to display selected object's attributes as an inputtext value in a dialog (I intend to implement editing that object later, that's why I'm displaying it in an inputtext).

I'm getting the following error:

VM93567:77 TypeError: Cannot read property 'id' of undefined at DebugAppView._View_PetsComponent0.detectChangesInternal (PetsComponent.template.js:383:44) at DebugAppView.AppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :234:14) at DebugAppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :339:44) at DebugAppView.AppView.detectViewChildrenChanges (eval at (http://localhost:8080/vendor.js:729:2), :260:19) at DebugAppView._View_AppComponent0.detectChangesInternal (AppComponent.template.js:96:8) at DebugAppView.AppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :234:14) at DebugAppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :339:44) at DebugAppView.AppView.detectViewChildrenChanges (eval at (http://localhost:8080/vendor.js:729:2), :260:19) at DebugAppView._View_AppComponent_Host0.detectChangesInternal (AppComponent_Host.template.js:36:8) at DebugAppView.AppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :234:14) at DebugAppView.detectChanges (eval at (http://localhost:8080/vendor.js:729:2), :339:44) at ViewRef_.detectChanges (eval at (http://localhost:8080/vendor.js:615:2), :124:65) at eval (eval at (http://localhost:8080/vendor.js:291:2), :415:84) at Array.forEach (native) at ApplicationRef_.tick (eval at (http://localhost:8080/vendor.js:291:2), :415:38) at ApplicationRef_.loadComponent (eval at (http://localhost:8080/vendor.js:291:2), :386:14) at eval (eval at (http://localhost:8080/vendor.js:291:2), :373:19) at eval (eval at (http://localhost:8080/vendor.js:291:2), :344:26) at ZoneDelegate.invoke (eval at (http://localhost:8080/polyfills.js:2780:2), :323:29) at Object.onInvoke (eval at (http://localhost:8080/vendor.js:567:2), :46:41) at ZoneDelegate.invoke (eval at (http://localhost:8080/polyfills.js:2780:2), :322:35) at Zone.run (eval at (http://localhost:8080/polyfills.js:2780:2), :216:44) at NgZoneImpl.runInner (eval at (http://localhost:8080/vendor.js:567:2), :77:71) at NgZone.run (eval at (http://localhost:8080/vendor.js:561:2), :228:66) at ApplicationRef.run (eval at (http://localhost:8080/vendor.js:291:2), :342:14) at ApplicationRef_.bootstrap (eval at (http://localhost:8080/vendor.js:291:2), :364:21) at eval (eval at (http://localhost:8080/vendor.js:291:2), :148:50) at ZoneDelegate.invoke (eval at (http://localhost:8080/polyfills.js:2780:2), :323:29) at Object.onInvoke (eval at (http://localhost:8080/vendor.js:567:2), :46:41) at ZoneDelegate.invoke (eval at (http://localhost:8080/polyfills.js:2780:2), :322:35) at Zone.run (eval at (http://localhost:8080/polyfills.js:2780:2), :216:44) at eval (eval at (http://localhost:8080/polyfills.js:2780:2), :571:58) at ZoneDelegate.invokeTask (eval at (http://localhost:8080/polyfills.js:2780:2), :356:38) at Object.onInvokeTask (eval at (http://localhost:8080/vendor.js:567:2), :37:41) at ZoneDelegate.invokeTask (eval at (http://localhost:8080/polyfills.js:2780:2), :355:43) at Zone.runTask (eval at (http://localhost:8080/polyfills.js:2780:2), :256:48) at drainMicroTaskQueue (eval at (http://localhost:8080/polyfills.js:2780:2), :474:36)

Here's my code:

Pet class

export class Pet {
id: number;
type: string;
price: number;

}

Component

import {Component, OnInit} from '@angular/core';
import {TestService} from './test.service'
import {Pet} from './pet'
import {DataTable, Column, Dialog, Button, InputText} from 'primeng/primeng';

@Component({
    selector: 'pets',
    template: require('./pets.component.html'),
    styles: [require('./pets.component.css')],
    providers: [TestService],
    directives: [DataTable, Column, Dialog, Button, InputText]
})
export class PetsComponent implements OnInit {
    pets: Pet[];
    selectedPet: Pet;
    displayPetDlg: boolean = false;
    cols: any[];
    error: any;

    constructor(private testService: TestService) {
    }

    ngOnInit() {
        this.getPetList();
        this.initCols();
    }

    getPetList() {
        this.testService
            .getPetList()
            .then(pets => this.pets = pets)
            .catch(error => this.error = error);
    }

    initCols() {
        this.cols = [
            { field: 'id', headerName: 'Id'},
            { field: 'type', headerName: 'Type'},
            { field: 'price', headerName: 'Price'}
        ];
    }

    onRowSelect(event: Event) {
        this.displayPetDlg = true;
    }

}

HTML template

<p-dataTable [value]="pets" selectionMode="single" [(selection)]="selectedPet" (onRowSelect)="onRowSelect($event)"> 
   <p-column *ngFor="let col of cols" [field]="col.field" [header]="col.header">
   </p-column> 
</p-dataTable>

<p-dialog header="Selected pet" [(visible)]="displayPetDlg" [modal]="true" [draggable]="false" [resizable]="false"> 
   <input type="text" pInputText [(ngModel)]="selectedPet.id" />
   <footer>
      <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
         <button type="button" pButton icon="fa-close" (click)="displayPetDlg=false" label="No"></button>
         <button type="button" pButton icon="fa-check" (click)="displayPetDlg=false" label="Yes"></button>
      </div>
   </footer> 
</p-dialog>

If I simply bind an object to an inputtext, there's no error and there's a [Object object] value in an inputtext. So I'm assuming that 'id' field of Pet object is not referenced properly (selectedPet.id).

So, what's the correct way of getting the selected row in a dialog (displaying object's fields)?

1
The error is probably caused by selectedPet not being set at all. What do you want it to be set to?Günter Zöchbauer
@GünterZöchbauer selectedPet is set to selected datatable row (see datatable selection attribute) and it is set correctly since I'm logging it in a onRowSelect function.peterremec
But it's probably set too late. Have you tried my answer?Günter Zöchbauer

1 Answers

0
votes

If you set selectedPet async, something like

[ngModel]="selectedPet?.id" (ngModelChange)="selectedPet ? selectedPet.id = $event : null"

might work for you.