1

In my implementation of adding charts to a react frontend, from gsheets, using an apps script backend, there seems to be some sort of an issue where my constructed base64 png string fails to be parsed properly. My flow is described below:

On the backend side, I call the charts from the sheet using

const charts = analytics.getCharts();

I then iterate through the charts using the code:

charts.forEach(function (chart, i) {
      chartBlobs[i] = chart.getAs('image/png').getDataAsString();
    });

I then return chartBlobs to the react frontend.

At the React Frontend, I receive the blobs using the code:

google.script.run.withSuccessHandler(setSheetCharts).getChartsFromSheet();

wrapped inside a use effect.

setSheetCharts is a function that sets the state of charts:

    const [charts, setCharts] = useState([]);
    const [loading, setLoading] = useState(true);
    const setSheetCharts = (vn) => {
        console.warn(vn)
        setCharts(getBase64ImageSrc(vn));
        setLoading(false);
    }

Since I return it as a blob. I have to now parse this blob. getBase64ImageSrc achieves this:

function getBase64ImageSrc(pngblobs) {
    console.warn(pngblobs);
    const imgSrcs = pngblobs.map((pngstring) => {
        const base64ImageString = Buffer.from(pngstring, 'binary').toString('base64');
        const srcValue = `data:image/png;base64,${base64ImageString}`;
        return srcValue;
    });
    console.warn(imgSrcs);
    return imgSrcs;
}

Now that charts has the src data, I just wrap it inside a dive and return:

<div>
    {charts.map((chart, index) => (
        <img key={index} src={chart} alt={`chart-${index}`} />
    ))}
</div>

But for some reason, the image fails to parse. Here are the results at different points:

An array is received at the client side:

0:"�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\...."
1:"�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\...."

How the getBase64ImageSrc parses and returns the srcs:

0:"data:image/png;base64,/VBORw0KGgoAAAANSUhEUgAAAyY..."
1:"data:image/png;base64,/VBORw0KGgoAAAANSUhEUgAAAyY..."

Seems fine to me, yet the image is not parsed properly..

Can anyone see what I am doing wrong here?

1 Answer 1

1

Although I'm not sure whether I could correctly understand your situation, from the following situation,

At the React Frontend, I receive the blobs using the code:

google.script.run.withSuccessHandler(setSheetCharts).getChartsFromSheet();

I think that in the current stage, chart.getAs('image/png').getDataAsString(); returns the string value converted from the blob. In this case, I'm worried that the converted values cannot be correctly used on the Javascript side. I guessed that this might be the reason for your current issue.

From your script in your question, it seems that you can use the image data as base64 data. So, how about directly sending the base64 data from Google Apps Script to Javascript with google.script.run.withSuccessHandler(setSheetCharts).getChartsFromSheet()? When this is reflected in your script, how about the following modification?

From:

chartBlobs[i] = chart.getAs('image/png').getDataAsString();

To:

chartBlobs[i] = `data:image/png;base64,${Utilities.base64Encode(chart.getAs('image/png').getBytes())}`; // or Utilities.base64Encode(chart.getBlob().getBytes()

By this modification, the data URL is put into chartBlobs. Furthermore, in order to use this data URL, please modify it as follows.

From:

const setSheetCharts = (vn) => {
    console.warn(vn)
    setCharts(getBase64ImageSrc(vn));
    setLoading(false);
}

To:

const setSheetCharts = (vn) => {
  console.warn(vn)
  setCharts(vn);
  setLoading(false);
}
  • I'm not sure about the details of setCharts of your script. So, the lower modification is my guess. So, please check this.

References:

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

3 Comments

Hey Tanaike, thank you for the response :) , will try this and update!
IT WORKED!! Thank you!! I had tried doing something similar before, but without the getBytes() function I guess something new to learn 👍
@mayank Thank you for replying and testing it. I'm glad your issue was resolved. Thank you, too.

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.