Search code examples
javascriptreactjsaxiosreact-bootstrap-table

How do I display base64 inside map loop(assumption) in ReactJS


I have a REST API that returns an image when I request with the url + (plus) file name and I want to display it in the image column in a table.

I use:
axios 0.18.0
reacj 16.13.0
react-bootstrap-table2-toolkit 1.3.1

My assumption is that react-bootstrap-table2-toolkit works like map function.

I have column that will render image like this:

{
      dataField: 'img_url',
      text: 'Image',
      formatter: (cell, row) => {
        let renderPosts = async () => {
          try {
            let res = await axios.get('https://myApiUrl:6601/'+cell,{
              responseType: 'arraybuffer' 
            });
            let posts = _imageEncode(res.data);
            console.log(posts)
            return <img src={`data:image/jpeg;base64,${posts}`} />
          } catch (err) {
            console.log(err);
          }
        }
        
        return renderPosts()
      } 
    },

But I got error like this:

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.



UPDATE

I changed the method above. by making this function outside of render() function

getImg = async (cell) => {
    try {
      let res = Promise.resolve(axios.get('https://myApiUrl:6601/'+cell,{
              responseType: 'arraybuffer' 
            }));
      return res.then(res=>{
        let mimetype="image/jpeg"
        let x =`data:${mimetype};base64,${btoa(String.fromCharCode(...new Uint8Array(res.data)))}`
        console.log(x)
        return x
      })
    } catch (err) {
      console.log(err);
    }
  }

then I use getImg() function inside formatter like this

{
      dataField: 'img_url',
      text: 'Image',
      formatter: (cell, row) => {
        let x = async () => await this.getImg(cell)
        return <img src={`${x()}`} />
      },
    },

but I got [object Promise] like this:
enter image description here

I mean just want to retrieve the result string from conversion to base64



I still new to this problem,
hope you can help, thanks:)


Solution

  • I see 2 problems in your updated method.

    First one is, getImg is not returning a promise. You are using Promise.resolve, but Promise.resolve is meant to be called at the end of the function with return, so you can't attach .then to it. Also, if you're using async, there is no need for any Promise syntax. Change getImg to this:

    getImg = async (cell) => {
      try {
        let res = await axios.get('https://myApiUrl:6601/'+cell,{
          responseType: 'arraybuffer' 
        });
        let mimetype="image/jpeg"
        let x =`data:${mimetype};base64,${btoa(String.fromCharCode(...new Uint8Array(res.data)))}`;
        console.log(x);
        return x;
      } catch (err) {
        console.log(err);
      }
    }
    

    Second thing is, you are creating a new function on each formatter loop, and it's redundant. Try this code:

    dataField: 'img_url',
    text: 'Image',
    formatter: async (cell, row) => {
      const x = await this.getImg(cell);
      return <img src={`${x}`} />
    },
    

    I recommend you read more about promises, async functions and the (syntax) differences between the two.

    Promises

    Async Functions

    Please note that the formatter function must wait for the promises, and I'm not sure it does.

    Let me know if you have any more questions.