0

Using [(ngModel)], I managed to set an inputs value based on a selected dropdown but I'm getting an error when compiling using ng build --configuration=prod, error shown is

Property 'name' does not exist on type 'any[]'

Property 'value' does not exist on type 'any[]'

when I compiled using ng serve, there was no error, Here is a stackblitz I created and what I have tried so far,

Typescript file:

  savedCards = [];
  selectedCard = '';

      selectDropdownCard(card) {
        this.savedCards.find((item) => item.id === card.id) ?
          this.savedCards = this.savedCards.filter((item) => item.id === card.id) :
          this.savedCards = [card];
        this.show = false;
        this.hasSelected = true;
        this.selectedCard = card;
      }

HTML file

<div class="div1" (click)="selectSavedCard()" [(ngModel)]="selectedCard" ngDefaultControl>
  <div *ngIf='!hasSelected'>
    <div>
      <p>dropdown</p>
    </div>
  </div>
  <div *ngFor="let card of savedCards">
    <div>
      <p>{{card.viewValue}}</p>
    </div>
  </div>
</div>

<div class="div2" *ngIf="show">
  <div *ngFor="let card of savedCreditCards" (click)="selectDropdownCard(card)">
    <div>
      <p>{{card.viewValue}}</p>
    </div>
  </div>
</div>

<input placeholder="id" [(ngModel)]="selectedCard.id" type="text">
<input placeholder="viewValue" [(ngModel)]="selectedCard.viewValue" type="text">
<input placeholder="name" [(ngModel)]="selectedCard.name" type="text">
<input placeholder="value" [(ngModel)]="selectedCard.value" type="text">

if I try added interface and use it as type, on ng build --configuration=prod I got no error, but on ng serve error shown are:

TypeError: Cannot read property 'value' of undefined

I could use some guidance and suggestions since I could not figure out how to solve this.

Community
  • 1
  • 1
hafizi hamid
  • 405
  • 2
  • 20
  • 41

4 Answers4

0

Instead of initializing selectedCard as an empty String, Initialize it as an empty Object, that should solve your problem, I hope this helps.

  selectedCard = {};
Hamza
  • 469
  • 3
  • 9
0

Have you tried to use an interface and use it as a type ?

interface Card {
    id: string;
    viewValue: string;
    name: string;
    value: string;
}
...
selectedCard: Card = { id = '', viewValue = '', name = '', value = '' };

Or have you tried something like that :

selectedCard = { id = '', viewValue = '', name = '', value = '' };
Nicolas T.
  • 36
  • 2
  • In your stackblitz, your are not using a property 'cardHolder'. Did you copy/paste all your code ? – Nicolas T. Aug 25 '19 at 16:35
  • I tried localy, i create an interface and put that : `selectedCard: Card = { id = '', viewValue = '', name = '', value = '' };`. (p.s: I forgot one `;` in the interface at `value: string`) and I have no **error**. – Nicolas T. Aug 25 '19 at 17:01
0

Looks like selectedCard is set to undefined or ''. So if you can assign the default value to selectedCard which could be first element of savedCreditCards then you should not get this error. I am not sure if that is possible for you to do but if it is then do:

savedCards = [];
  show = false;
  hasSelected: boolean;
  savedCreditCards: Card[] = [
    { id: '001', viewValue: 'Dropdown1', name: 'A' , value:'1' },
    { id: '002', viewValue: 'Dropdown2', name: 'B' , value:'2' },
    { id: '003', viewValue: 'Dropdown3', name: 'C' , value:'3' },
    { id: '004', viewValue: 'Dropdown4', name: 'D' , value:'4' },
  ];
  selectedCard = this.savedCreditCards[0];

This should resolve the problem. Another way could be to wrap your html code with *ngIf like this:

<div *ngIf="selectedCard">
    <input placeholder="id" [(ngModel)]="selectedCard.id" type="text">
    <input placeholder="viewValue" [(ngModel)]="selectedCard.viewValue" type="text">
    <input placeholder="name" [(ngModel)]="selectedCard.name" type="text">
    <input placeholder="value" [(ngModel)]="selectedCard.value" type="text">
</div>

This I think might be neater solution. In this case you don't have to assign a default value.

Pankaj Shukla
  • 2,657
  • 2
  • 11
  • 18
0

Look at your prod configuration. You are using AOT

You might want to try "ng serve --aot" for testing

You would find that you set a string type for selectedCard due to type inference. I think the stackblitz has been updated, but be careful with your references.

I definitely agree that you are using typescript, so use an interface and get the types more explicitly defined. You could have avoided this error by using explicit types, which is the main advantage of TS

devBrandon
  • 131
  • 4