How to utilize byte arrays for loading images in Angular

I have the following method within my Angular component:

<li *ngFor="let item of list1._subList" onclick="SelectImage()" class="active">
              <img alt="img"  [src]="getImage(resp.data_values[0])| secure | async"
              />
              <p>{{generateDisplayImgName(item.values[0])}}</p>
            </li>



 getImage(ficname: string) {
     let obj: any;
     // remember 5th question represents the zip file name
    obj = {"fileName":StringUtil.extractSubstring(5,ficname.length,ficname),"zipFileName":this.something,"terminalTypeId":5}
    return this.projectService.extractStudioImage(this.id1,this.id2,this.id3,obj).subscribe((data)=>{

      let objectURL = 'data:image/png;base64,' + data;
      if(ficname.includes('jpg')){
        objectURL = 'data:image/jpg;base64,' + data;
      }
      console.log(objectURL);
      return objectURL;
    })
  }

Below is the code for my HttpClient.

extractStudioImage(id1,id2,id3,json){
      const headers = new HttpHeaders();

      let params = new HttpParams();
      params = params.set('a1', id1);
      params = params.set('a2',id2);
      params = params.set('a3',id3);

    return this._http.post(ServerAddress.getInstance().getValue() + this.extractStudioPhotoUrl, json,{
        headers: headers,
        params:params,
      });
    }

The method works fine as I can see the images in Fiddler. However, the issue arises because Angular keeps trying to parse JSON (the byte representation of my image) even though I am not explicitly attempting to do so.

Upon inspecting with my Chrome debugger, I notice the following error: It is an HttpResponseError

Unexpected token in JSON at position 0

I am not sure what is causing this error in my implementation.

Answer №1

This error occurs because the http module within your service expects a response type of json by default.

To resolve this, you must specify it to accept "blob" and also include the Accept: image/png header.

extractStudioImage(id1,id2,id3,json) {
  const headers = new HttpHeaders();
  headers.append("Accept", "image/png");
  
  let params = new HttpParams();
  params = params.set('a1', id1);
  params = params.set('a2',id2);
  params = params.set('a3',id3);

  return this._http.post(ServerAddress.getInstance().getValue() + this.extractStudioPhotoUrl, json,
    {
      responseType: "blob",
      headers: headers,
      params: params
  });
}

Then, generate the URL from the blob in your component:

getImage(ficname: string) {
   let obj: any;
   // Note that the 5th question represents the zip file name
  obj = {"fileName":StringUtil.extractSubstring(5,ficname.length,ficname),"zipFileName":this.something,"terminalTypeId":5}
  return this.projectService.extractStudioImage(this.id1,this.id2,this.id3,obj).subscribe((data)=>{

    const objectURL = URL.createObjectURL(da);
    console.log(objectURL);

    return objectURL;
  })
}

Answer №2

I have managed to find the resolution.

Within the HTML portion, I can achieve this by:

<img alt="img" [id]="generateDisplayImgName(resp.data_values[0])" #refEl [src]="loadImageFromLocalStorage(generateDisplayImgName(resp.data_values[0]),refEl)"

 getImage(ficname: string){
     let obj: any;

     // keep in mind that the 5th question represents the name of the zip file
      obj = {"fileName":ficname,"zipFileName":this.c._list.filter(a=>a.qN===5)[0].answer,"typeId":5}
      this.projectService.extractStudioImage(this.a,this.b,this.c,obj).subscribe((data:Blob)=>{

        this.createImageFromBlob(ficname,data);
        return this.imageBlobUrl;
    });
  }

  createImageFromBlob(ficname:any , image: Blob) {
    let reader = new FileReader();
    reader.addEventListener("load", (evt) => {
      let res = evt.target.result;

      // Save Data URL in localStorage
      try {
        if (typeof res === "string") {
          localStorage.setItem(ficname, res);
          this.dixieDbService.addNewImage("giobu"+ficname, res).then(r => console.log("inserted: "));
        }
      }
      catch (e) {
        console.log("Storage failed: " + e);
      }
    }, false);
    if (image) {
      reader.readAsDataURL(image);
    }
  }

The technique involves utilizing blobs and managing them with try/catch statements and events. This approach allows us to properly handle the stream as it comes in.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the best practices for effectively using RxJs subscriptions?

I'm looking for some advice on how to handle Angular and RxJs mechanics. I have server-side pagination set up on my backend and three components on the frontend: a data list, filters, and a pagination component. How can I subscribe to two streams (pag ...

Having trouble getting Angular PWA configured properly

I've been trying to configure my Angular project as a progressive web app following the official documentation. However, I encountered an error when attempting to run it on my local server. The error message displayed is "GET /" Error (404): "Not foun ...

How can I make Cesium, SystemJS, and Angular2 compatible with each other?

Could anyone provide a working example of using SystemJS (not Webpack) with Angular2 (in TypeScript, not Dart) and Cesium (npm)? I came across a blog post on cesiumjs' site that discusses this: The author mentioned, "You can't simply do a requi ...

The Ionic2 slider appears to be experiencing difficulties when used in conjunction with *ngFor in Angular2

Issue with Screen Prints!! After clicking the Skip button, unexpectedly the Login page appears! https://i.sstatic.net/2Enng.png Encountering the Login Page! Furthermore, if you click on the Home icon, the Slider page will be displayed!! https://i.ssta ...

Executing a series of asynchronous HTTP calls in Angular until a specific condition is satisfied

In Angular, I am making an HTTP call that returns a promise. Currently, I am refreshing the call using setTimeout at regular intervals. Are there any built-in functions or design patterns available to handle this task more efficiently? ...

Using ngModel with a dynamic variable

Having a issue with using ngModel to pass a value to bump object property retrieved from the bumpDetail.name array. I've included my code snippet below. Can someone please review it and point out where I've made a mistake? Thank you. <p * ...

The attribute interface overload in Typescript is an important concept to

Consider a scenario where there are multiple payload options available: interface IOne { type: 'One', payload: { name: string, age: number } } interface ITwo { type: 'Two', payload: string } declare type TBoth = IOne ...

Error in compiling caused by an absent property on JSX element

While working with material-ui, I came across a Slider element: <Slider ... sliderStyle={{}} ...> An error message popped up: error TS2339: Property 'sliderStyle' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttri ...

The upcoming developer manages to execute the program successfully, however, it continues to load indefinitely

Executing the command yarn dev consistently runs successfully in my VS Code terminal: $ yarn dev yarn run v1.22.19 warning ..\..\..\..\package.json: No license field $ next dev ready - started server on 0.0.0.0:3000, url: http://localho ...

Should I avoid incorporating jQuery into Angular applications?

I'm curious about whether it's best to steer clear of using jQuery in an Angular application, considering the idea that only one entity should be handling DOM manipulation. Has anyone encountered situations where jQuery was the necessary quick fi ...

Updating the JWT token in Angular 6 and making a new request with the updated token

When my JWT authentication token expires (verified by the backend), I need to call a refresh token API and resend the last failed request due to the expired token. I have an Interceptor in place, but I must update the authentication header before sending ...

Different ways to categorize elements of Timeline using typescript

I have some code that generates a timeline view of different stages and their corresponding steps based on an array of stages. Each stage includes its name, step, and status. My goal is to organize these stages by name and then display the steps grouped un ...

Deep copying with Object.assign can lead to unexpected issues

I am currently working with an object array that needs to be transformed before it is sent to the controller. Here is the Angular code snippet I am using: sourceObjArray: SourceObject[] = [..]; targetObjArray: SourceObject[]= []; targetObjArray = object. ...

Encountering a navCtrl problem in Ionic 3 while attempting to utilize it within a service

I am currently working on a feature to automatically route users to the Login Page when their token expires. However, I am encountering an issue with red lines appearing under certain parts of my code. return next.handle(_req).do((event: HttpEvent< ...

Is there a way to position the Image component from next/image using absolute positioning?

Is it possible to use an element Image from 'next/image' with the CSS style { position: absolute; left: 50% }? It appears that it is not being applied. For example: import React from 'react' import Image from 'next/image' imp ...

What are some ways to leverage a promise-returning callback function?

Here is a function that I have: export const paramsFactory = (params: paramsType) => { return ... } In a different component, the same function also contains await getPageInfo({ page: 1 }) after the return .... To make this work, I need to pass a cal ...

The variable <variable> is not meeting the 'never' constraint. Error code: ts(2344)

Currently, I am attempting to utilize Supabase alongside TypeScript. However, I encounter an error when trying to use functions like insert(), update(), upsert(), etc. Specifically, the issue arises when declaring the object I want to declare: "Type & ...

Is there a way to update the text of a button when it is clicked?

Is there a way to dynamically change the text of a button when it is clicked and revert back to its original text when clicked again? I have attempted something along these lines, but I am unsure how to target the text since there isn't a property si ...

Execute the ngFor directive multiple times

Currently, I am working with Angular 7. I have an array that I am iterating through using the typical ngFor directive in my HTML: <mat-card *ngFor="let card of cardNames"> Is there a method to loop through the elements in the cardNames array more ...

What steps can I take to stop a browser from triggering a ContextMenu event when a user performs a prolonged touch

While touch events are supported by browsers and may trigger mouse events, in certain industrial settings, it is preferred to handle all touch events as click events. Is there a way to globally disable context menu events generated by the browser? Alternat ...