2

I'm trying to send to the template some image information after validation. But I'm not getting.

The variables that go to the template are within a callback, or are within an asynchronous function, and I do not know to send this information to the template.

Could help me solve this problem? I've tried everything.

event.component.ts

import "rxjs/Rx";
import {Component} from '@angular/core';

@Component({
    selector: '<my-image></my-image>',
    templateUrl: './event.component.html',      
})
export class EventComponent {
    files: File[];
    file: any
    imageName: any;
    imageSize: any;
    whithImage = false;

    ngOnInit() {this.files = []}

    onFileSelect(event) {
        this.files = event.dataTransfer ? event.dataTransfer.files : event.target.files;
        this.file = this.files[0];
        this.isImage(this.file, function(res, file){
            if(res==true){
                this.imageName = file.name;
                this.imageSize = file.size;
                this.whithImage = res;
            }
        }) 
    }

    isImage(file, callback) {
        var reader = new FileReader();
        reader.onload = function(event) {
            var contents = reader.result;
            var buf = new Uint8Array(contents);
            if(buf[0] === 0xFF && buf[1] === 0xD8 && buf[2] === 0xFF){
                callback(true, file) //jpg
            }else{callback(false)}
        };
        reader.readAsArrayBuffer(file);
    }

    onChooseClick(event, fileInput) {
        fileInput.value = null;
    }

event.component.html

<span (click)="onChooseClick($event, fileinput)">
    Image<input  #fileinput type="file" (change)="onFileSelect($event)"/>
</button>
<div *ngIf="whithImage">
    <p>{{ imageName }}</p>
    <p>{{ imageSize }}</p>
</div>

1 Answers1

3

Try what @peeskillet suggested first – i.e., use the proper this context by using an arrow function:

export class EventComponent {
   onFileSelect(event) {
        ...
        this.isImage(this.file, (res, file) => {     // <----
            if(res==true) {
                this.imageName = file.name;
                this.imageSize = file.size;
                this.whithImage = res;
            }
        }); 
    }

If that doesn't work, then Angular not does know how to monkey-patch your asynchronous event, hence when the event fires, Angular change detection doesn't run (so your view doesn't update to reflect the new component property values). You'll need to manually trigger change detection. Here's one way to do it:

import {ChangeDetectorRef} from '@angular/core';     // <-----
export class EventComponent {
   constructor(private cdref:ChangeDetectorRef) {}   // <-----
   onFileSelect(event) {
        ...
        this.isImage(this.file, (res, file) => {     // <----
            if(res==true) {
                this.imageName = file.name;
                this.imageSize = file.size;
                this.whithImage = res;
                this.cdref.detectChanges();          //  <------
            }
        }); 
    }
Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 2
    Looks more like the problem is the use of `function` and `this` ;-) – Paul Samsotha Oct 01 '16 at 03:36
  • Thank you Mark for his contribution, but even commenting the functions `imageName, imageSize and whithImage` and leaving only `this.cdref.detectChanges();` the following error appears: `Cannot read property 'cdref' of undefined` –  Oct 01 '16 at 12:56
  • @MarkRajcok Hi, can you please have a look at [this](https://stackoverflow.com/q/49295365/8494729) question? – noobie Mar 15 '18 at 10:19