2

Hoping someone can teach me something new, I'll try to keep it short since I'm betting it's just some inane detail I'm hopefully missing...

I start with an image like so, where currentImage is an existing image path to act as a default at first;

<img src="{{currentImage}}">
<input type="file" (click)="onUpload($event)">

Which then fires off a basic method to grab the event.files etc like so;

onUpload(event) {

      const file: File = event.files[0],
          reader: FileReader = new FileReader(),
           that = this; // *** WORTH NOTING...

      reader.addEventListener('loadend', function () {
        console.log('the resulting base64 string = ', reader.result);
        that.currentImage = reader.result;
      }, false);

      if (file) {
        reader.readAsDataURL(file);
      }

      console.log('does the blob get updated to currentimage?',
                   this.currentImage); // THIS RETURNS THE OLD IMAGE PATH***

  }

This sort of works, I see the base64 string I want in the console, I see the currentImage var string update to the base64 string in the html binding {{currentImage}}, and I see the img element flash the newly updated image...but then it immediately reverts right back to the default image originally assigned to currentImage even though currentImage still has the new base64 string.... Also the last console.log for this.currentImage shows the original file path.

I can not for the life of me figure out yet why but am new to the web side with FileReader, Angular etc. So hopefully somebody can serve me a quick slice of humble pie?? :)

PS - If it matters, it's angular 5

1
  • Please see my answer below, it was not a fair question in the first place. Cheers! Commented Jan 12, 2018 at 17:14

5 Answers 5

1

this.currentImage in console log executes first and console.log in reader executes later. You just binded the event and then tell browser to load, meanwhile browser loads the image and trigger the event, the last console.log would have been already executed.

More code or live example will help to find out why the image goes out after first load.

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

1 Comment

hmmm, why does the img src not update? I can put together a better example a bit later when I have a little more time, right now though I'm beat and need sleep. I get the order of operation part, but maybe I'm just too sleepy at the moment to have a functioning brain lol.
1

You have to change the (click) to (change) method

html

<img src="{{currentImage}}">
<input type="file" (change)="onUpload($event)">

typescript

currentImage = "";


public onUpload(event){
    let reader = new FileReader();
    reader.addEventListener("load", (ev)=>{
        this.currentImage  = ev.target['result']
    });
    reader.readAsDataURL(event.target.files[0]);
}

hope it helps.

working demo: https://stackblitz.com/edit/angular-z774jn?file=app%2Fapp.component.ts

Comments

1

Replace (click) event bind to (change) in html

<img [src]="currentImage">
<input type="file" (change)="onUpload($event)">

And in ts pass the e inside addEventListener callback

 onUpload(e) {
    const file: File = e.dataTransfer ? e.dataTransfer.files[0] : e.target.files[0],
    reader: FileReader = new FileReader(),
    that = this; // *** WORTH NOTING...
    reader.addEventListener('load', function (e) {
      console.log('the resulting base64 string = ', e.target.result);
      that.currentImage = e.target.result;
    }, false);
    if (file) {
      reader.readAsDataURL(file);
    }
    console.log('does the blob get updated to currentimage?',
    this.currentImage); // THIS RETURNS THE OLD IMAGE PATH***
 }

Comments

1

Change (click) to (change) and use following code snippet.

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular 5';
 currentImage ;
  onUpload(event) {
    if (event.target.files && event.target.files[0]) {
      const reader = new FileReader();
      reader.onload = (rdr) => {
        this.currentImage = reader.result;
      };
      reader.readAsDataURL(event.target.files[0])
    }
  }
}

WORKING DEMO

Comments

0

So I need to apologize for the sleep deprived question. I left out the fact that there was also some advanced image manipulation involved that the base64 needed to interact with accordingly and the property bindings just weren't fast enough to catch up to the next step. As far as I'm concerned all your answers are correct, and I just poorly asked the question in the first place. So mea culpa, after getting some sleep I found the culprit pretty quick in an unrelated area. Thank you so much for sparing the time, I'll delete the question shortly. Cheers!

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.