0

I'm working on Angular4 project. I get Blob returned from my API call, then I convert it to base64 but can't manage to save it to the array of pictures (so I can show it with *ngFor later).

Here is my API call:

getImg(): Observable<Blob> { const path = *can't show this part*; return this.http.get(path, { responseType: "blob" }); }

And here is what I tried so far:

This function has error at line this.images[i] = reader.result;, because it says Property 'images' does not exist on type 'FileReader'

images: Array<any> = [];

getImages(): void {
for (var i = 0; i < this.myData.length; i++) {
  this.myApiCalls.getImg()
    .subscribe(res => {
      var reader = new FileReader();
      reader.readAsDataURL(res);
      reader.addEventListener("loadend", function () {
        this.images[i] = reader.result;
      });       
    },
      err => {
        console.log(err.message)
      });
  }
}

The other thing I tried is with callbacks, but I still got error, on the same column but for different thing. It says 'this' implicitly has type 'any' because it does not have a type annotation.

getImages(): void {
for (var i = 0; i < this.myData.length; i++) {
  this.myApiCalls.getImg()
    .subscribe(res => {
      this.readImageFile(res, function(e: any) {
        this.fields[i] = e.target.result;
      });       
    },
      err => {
        console.log(err.message)
      });
  }
}

readImageFile(response: Blob, callback: any): void {
   var reader = new FileReader();
   reader.readAsDataURL(response);
   reader.onloadend = callback 
} 

So I get data returned back correctly, but the problem is I can't manage to save it to the array. If you guys are able to help me solve that problem I would be very happy. Thank you.

1
  • hey, @HC1122 Did you tried what iam said as comment? Commented Jun 13, 2018 at 14:50

3 Answers 3

1

Why are you converting it to a base64? You can create a url from the blob with const blobUrl = URL.createObjectURL(blob) (just remember to revoke the url to free mem after it's not used with URL.revokeObjectURL(blobUrl))? I ask because it's more efficient.

But your code is failing because of a context issue (this is not what you expect). The context inside the callback is the reader object. There's a clue in the error Property 'images' does not exist on type 'FileReader' - it's showing that this is an instance of FileReader.

Edit: You should also use let on your loop i, otherwise i won't be what you expect inside the callback.

If you want to preserve the outer scope context then use an arrow function:

getImages(): void {
for (let i = 0; i < this.myData.length; i++) {
  this.myApiCalls.getImg()
    .subscribe(res => {
      var reader = new FileReader();
      reader.addEventListener("load", () => {
        this.images[i] = reader.result;
      });
      reader.readAsDataURL(res);
    },
      err => {
        console.log(err.message)
      });
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Note that I made another edit about using let @HC1122
I recommend you console log this in and out of the 'load' callback and make sure it's what you expect and that it has an images array
1

Here is updated your code please try this once.

images: any[]= [];

getImages(): void {
for (var i = 0; i < this.myData.length; i++) {
  this.myApiCalls.getImg()
    .subscribe(res => {
      this.readImageFile(i,res);
    },
      err => {
        console.log(err.message)
      });
  }
//here iam logged console. See values saved array or not.
console.log("Print your Value here once",this.images);
}

readImageFile(indexVal:number,response: Blob): void {
      let self = this;
      var reader = new FileReader();
      reader.readAsDataURL(response);
      reader.onloadend = function () {
          self.images[indexVal] = reader.result;
        }
} 

Try this once and let me know. I hope its useful to solve your problem. I all ready worked related this function

Thanks,

Muthukumar

7 Comments

Hm, currently I got error self.images[indexVal] is undefined in console.log
did you print same like this console.log("Print your Value here once",this.images);?
reader.onloadend = function () { //please here first log your output has been got or not once pls. console.log("Reader Value",reader.result); self.images[indexVal] = reader.result; }
Karnan thank you for your help. The problem was like commented below in using var i instead of let i and because of that Indexes were not as expected.
ok change like that and try one more time you got as your output has been expected
|
0

Try this answer, it may be helpful https://stackoverflow.com/a/16245768/8350917

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.