0

I am trying to prevent from having to call the fetch for the profile pic upon loading the page. I get the image as a blob, and I convert it into an object url and then store it in the local storage. I noticed that upon refreshing the page the image is erroring out and I am not sure why that is the case, does the object url not save in local storage? If so how can I save the data for the image?

axios({
        url:   '/users/avatar',
        method: 'GET',
        headers: {
          'Authorization': "Bearer " + token,
        },
        data: {avatar: avatarUrl},
        responseType: 'blob',
      }).then((response) => {
        log(response);
        let blob = URL.createObjectURL(response.data)
        localStorage.setItem('image', blob);

}
scotth527
  • 77
  • 2
  • 10
  • can you check in crome localstorage that your image is saved after fetching from api or not? – akhtarvahid Nov 14 '19 at 03:24
  • Yes so upon saving after fetching it appears like this. ` blob:http://localhost:3000/83bc8dcd-bb56-49cb-a9a7-81c66d872a03 ` Sometime after refreshing it turns to this ` /static/media/default.c7401ecc.png ` – scotth527 Nov 14 '19 at 13:35
  • the second one is the default image that the onerror function defaults to. I think your solution isn't working cause at thee point wheere it is turned into an object url it's already a string. – scotth527 Nov 14 '19 at 13:50

2 Answers2

0

Use DataURL instead of ObjectURL! The localStorage can only manage 16 bit unicode String object.

Try replace

let blob = URL.createObjectURL(response.data)
localStorage.setItem('image', blob);

... by this code:

var arr = new Uint8Array(response.data);

// Convert the int array to a binary string
// We have to use apply() as we are converting an *array*
// and String.fromCharCode() takes one or more single values,
// not an array.
var raw = String.fromCharCode.apply(null, arr);

//convert binary to ascii
var b64 = btoa(raw); 

//a DataURL is a Base64 string with a header
var dataURL = "data:image/jpeg;base64," + b64;

//do your thing
localStorage.setItem('image', dataURL);

For the Axios responseType you need to try something else than 'blob'. The options are: 'arraybuffer', 'document', 'json', 'text', 'stream'. With 'arraybuffer' you can have:

var arr = response.data;
Dan Froberg
  • 168
  • 8
-1
axios({
        url:   '/users/avatar',
        method: 'GET',
        headers: {
          'Authorization': "Bearer " + token,
        },
        data: {avatar: avatarUrl},
        responseType: 'blob',
      }).then((response) => {
        log(response);
        let blob = URL.createObjectURL(response.data)
        localStorage.setItem('image', JSON.stringify(blob));

}

get like this

let getImage = JSON.parse(localStorage.getItem('image'));
akhtarvahid
  • 9,445
  • 2
  • 26
  • 29
  • what's the point of stringifying a string? The return value of `URL.createObjectURL` is a string, and you are further calling `JSON.stringify` on that string. – trusktr Dec 11 '22 at 05:49