简体   繁体   中英

Angular2 binding error “Cannot read property 'size' of undefined”

I'm trying to clone https://imageresize.org/ for practicing Angular 5. However, i'm facing a problem which prevents me from binding the value from typescript file to html.

Here is the input:

<input type="file" accept="image/*" autocomplete="off" style="display: none" id="input" draggable="true" (change)='changeInput()' multiple>

I'm also using xkeshi's image compressor ( https://github.com/xkeshi/image-compressor ) to compress the image:

changeInput() {
    this.img = <HTMLImageElement>document.querySelector('img,#image');
    this.files = (<HTMLInputElement>document.querySelector('input[type=file],#input')).files
    this.inputFlag = true;
    for (var i = 0; i < this.files.length; i++) {
      var imageCompressor = new ImageCompressor;
      imageCompressor.compress(this.files[i],{
        quality: .4
      }).then((result)=>{
        this.results[i] = result;
        this.resultSize = result.size;
        this.sizeRound = `${Math.round(100 - this.resultSize * 100 / this.fileSize)}%`;
      })
    }
  }

results is an array of Blob to get the value of "result" in a loop:

results: Blob[] = [];

HTML binding:

<tr *ngFor ="let file of files, let i = index">
                  <td style="height: 30px"  class="text-center">{{file.name.slice(0,7)}}</td>
                  <td style="height: 30px"  class="text-center">{{status}}</td>
                  <td style="height: 30px"  class="text-center"></td>
                  <td style="height: 30px"  class="text-center">{{file.size}}</td>
              <td style="height: 30px"  class="text-center">{{results[i].size}}</td>
              <td style="height: 30px"  class="text-center">{{sizeRound}}</td>
            </tr>

The error i get: a printscreen of the error Does anyone have any ideas how to fix this? Thank you. p/s: sorry for my English, i'm not a native speaker

As for as I understand, angular starts putting values as soon a component launches when the value might not be available. So either size really does not exist on the object or its value is not available at the moment.

Try using optional values:

<td style="height: 30px"  class="text-center">{{file?.size}}</td>

您可以使用条件运算符先尝试检查数组!= null,然后再尝试访问它。

<td style="height: 30px"  class="text-center">{{results ? results[i]?.size : null}}</td>

It may be because of async issue in Angular, "results" is not yet derived as you expect.

<td style="height: 30px"  class="text-center">{{results ? results[i]?.size : null}}</td>

Also in the component, call the results explicitly through some method like below.

changeInput() {
    this.img = <HTMLImageElement>document.querySelector('img,#image');
    this.files = (<HTMLInputElement>document.querySelector('input[type=file],#input')).files
    this.inputFlag = true;
    for (var i = 0; i < this.files.length; i++) {
      var imageCompressor = new ImageCompressor;
      imageCompressor.compress(this.files[i],{
        quality: .4
      }).then((result)=>{
        //this.results[i] = result;
        this.refreshResults(i, result);
        console.log(this.results);
        this.resultSize = result.size;
        this.sizeRound = `${Math.round(100 - this.resultSize * 100 / this.fileSize)}%`;
      })
    }
  }

refreshResults(index, result) {
    this.results[index] = result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM