8

I am fetching an image via a http request which returns a blob and i want to assign the blob returned to an image src.

http request:

   const options = {
        headers,
        responseType: 'blob' as 'json'
    };

    return this.httpClient.get(url, options)

component.ts

async ngOnInit() {
   this.frontImageSrc = getImage()
}

async getImage() {
    const image = await this.service.imageRequest(id, "front", token).toPromise();
    var imageUrl = URL.createObjectURL(image)
    return imageUrl
}

component.html

  <img src={{frontImageSrc}} alt="image"/>

The image src does not get assigned and in the console i can see the following.

blob:http://localhost:4200/f846a3aa-8cd3-4876-8dd3-972c9469feb2 14:00:00.664 unsafe:blob:http://localhost:4200/f846a3aa-8cd3-4876-8dd3-972c9469feb2:1 GET unsafe:blob:http://localhost:4200/f846a3aa-8cd3-4876-8dd3-972c9469feb2 net::ERR_UNKNOWN_URL_SCHEME

5
  • Are you getting proper response from the API? Commented Feb 11, 2020 at 14:07
  • I think issue is that angular sanitizes your link, you can use Sanitzer and bypassSecurity to see if it works. Also it's better to use property binding instead of binding literal like [src]="frontImageSrc". Besides that don't forget to revoke your blob url in ngOnDestroy. If this works I can post it as an answer. Commented Feb 11, 2020 at 14:08
  • @Arcteezy Yes i am Commented Feb 11, 2020 at 14:11
  • @BlindDespair Can you post an answer with the use of Sanitizer bypassSecurity, i don't know how they work. Commented Feb 11, 2020 at 14:12
  • done, hope it helps you Commented Feb 11, 2020 at 14:18

1 Answer 1

13

Message about :unsafe stuff means that angular sanitised your url, because it considers it unsafe. Cleanest way to work this around is to introduce a pipe (although it is not necessary): like so:

@Pipe({ name: 'safeResourceUrl' })
export class SafeUrlPipe implements PipeTransform {
  constructor(private readonly sanitizer: DomSanitizer) {}

  public transform(url: string): SafeResourceUrl {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

Then in your component you can the following:

component.html

  <img [src]="frontImageSrc | safeResourceUrl" alt="image"/>

component.ts

async ngOnInit() {
   this.frontImageSrc = getImage()
}

async getImage() {
    const image = await this.service.imageRequest(id, "front", token).toPromise();
    var imageUrl = URL.createObjectURL(image)
    return imageUrl
}

ngOnDestroy() {
  URL.revokeObjectURL(this.imageUrl)
}

Of course you can do bypassing in your ngOnInit instead, but it's cleaner to use pipe. Also since url is created asynchronously it might make sense to do a null check in the template.

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

2 Comments

This works great! I am trying to use the "angular-x-image-viewer" component to display the image. This component takes an array of strings as source [src]. How can be applied the pipe in this case? I dont know how the html syntax would look like.
@RickyTad in case you need an array, you need to bypass security for each item in it, you can extend pipe to accept array or 1 string and if it's array then map it. or you can just do this on component level

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.