1

I have a problem in my Angular 6 application and really can't find answer right now so please help me if you can. Thank you. The problem is next:

I have an array (userDocuments) with this content:

[{"DocumentId":1,"DocumentName":"Osobna iskaznica","Mark":"13994000"},{"DocumentId":2,"DocumentName":"Putovnica","Mark":"qprtobm777"}].

Dropdown is being populated from this array. Beside dropdown is button which is used for editing selected element content in dialog box.

<select id="select-document" class="form-control" [(ngModel)]="selectedDocumentId">
    <option *ngFor="let document of userDocuments" [value]="document.DocumentId">
    {{ document.DocumentName }} ({{ document.Mark }})</option>
    </select>
<button class="btn btn-danger btn-40 ml-1" type="button" (click)="openDocumentDailog(true)"> <i class="fa fa-edit"></i></button>

After component init when dropdown is being populated and hitting edit button dialog opens with data of selected array element. Everything works fine. Then I choose second value from dropdown and getting error about undefined element. Here is calling method for edit:

openDocumentDailog(edit: boolean) {
    const currentDoc = this.userDocuments.find(x => x.DocumentId === this.selectedDocumentId);
    console.log('array: ' + JSON.stringify(this.userDocuments));
    console.log('DocumentId: ' + this.selectedDocumentId);
    console.log(this.userDocuments.find(x => x.DocumentId === this.selectedDocumentId));

    const dialogRef = this.dialog.open(NewDocumentComponent, {
      width: '400px',
      data: {
        userId: this.loggedUser.id,
        edit: edit,
        docId: edit ? currentDoc.DocumentId : null,
        docName: edit ? currentDoc.DocumentName : null,
        docMark: edit ? currentDoc.Mark : null
      }
    });

...

For variable currentDoc I'm getting error that is undefined in second search. As you can see I'm logging values. Here are results:

array: [{"DocumentId":1,"DocumentName":"Osobna iskaznica","Mark":"13994000"},{"DocumentId":2,"DocumentName":"Putovnica","Mark":"qprtobm777"}]

DocumentId: 1

Object { DocumentId: 1, DocumentName: "Osobna iskaznica", Mark: "13994000" }

array: [{"DocumentId":1,"DocumentName":"Osobna iskaznica","Mark":"13994000"},{"DocumentId":2,"DocumentName":"Putovnica","Mark":"qprtobm777"}]

DocumentId: 2

undefined

In code to me everything looks correct because documentId value (1 or 2) is present in one of array elements. Also I need to say when I choose back first value from dropdown also getting an error message of undefined element. After first edit next edits are not working anymore because of array.find method.

Am I missing something or is problem somewhere deeper? Thank you.

Zeljko

3
  • After two days of headache and immediately after posting the case I found that problem was with ...find(x => x.DocumentId === this.selectedDocumentId) but not sure why. In typescript selectedDocumentId is specified as a number (variable associated to dropdown ngModel) so everything looks correct in values comparing. Just in case I added plus(+) before this.selectedDocumentId for casting to number and look now app works. Don't know why. Any idea? Commented Feb 10, 2019 at 13:30
  • No I don't have. Commented Feb 10, 2019 at 13:30
  • I tried now with some selectedDocumentId initial value but without casting to number still doesn't work. Commented Feb 10, 2019 at 13:34

3 Answers 3

1

In comparison, we need to remember that === checks the value and the type. In your json, the id's are of type number, but whereas in your template you are using value that defaults to a string. If you want to keep your id as a number, you need to use [ngValue]:

<select id="select-document" class="form-control" [(ngModel)]="selectedDocumentId">
  <option *ngFor="let document of userDocuments" [ngValue]="document.DocumentId">
    // ...
  </option>
</select>

StackBlitz

Sign up to request clarification or add additional context in comments.

1 Comment

yes that's it. I changed to ngValue. Thank you 100x! :)
0

Is selectedDocumentId already initialized ?

you can do something like:

// the dropdown will select the first item by default
    constructor() {
      this.selectedDocumentId = this.userDocuments[1].DocumentId;
    }

Second:

const currentDoc = this.userDocuments.find(x => x.DocumentId === this.selectedDocumentId);

x.DocumentId is a int but this.selectedDocumentId is a string, you compare an int with a string with ===.

solution:
You can either do {"DocumentId":"1"(string),"DocumentName":"Osobna iskaznica","Mark":"13994000"}, ...

or do x.DocumentId === parseInt(this.selectedDocumentId,10) to solve the problem.

1 Comment

Yes it is when array is filled with data. As stated below in answer I changed code from value to ngValue to keep variable as a number and now is all ok. Thank you.
0

You're using strict comparison (e.g., ===), and it'is only true if the operands are of the same type and the contents match. The contents (DocumentId & this.selectedDocumentId) match, but operands are of different types. Try to use == instead of ===, it seems that it doesn't find your document because of this:

const currentDoc = this.userDocuments.find(x => x.DocumentId == this.selectedDocumentId);

stackblitz

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.