9

I am calling an api and getting pdf in return.

fetch(`api` + guid, {
   method: "GET",
   headers: {
    "Accept": "application/octet-stream",
    "Authorization": "Bearer " + token,
   },
   responseType: 'arraybuffer',
})
.then((res) => res.text())
.then((data) => {
    fs.writeFileSync('file.pdf', data);
});

I get the pdf file but the issue is the pdf file is always empty. But when I accept response as json, it works fine.

I found similar problems like this but none of the solution worked for me yet.

It would be great if someone can point out the issue.

4 Answers 4

15

I found the issue. As I am using fetch not Axios. We cannot pass responseType as Fetch's option.

fetch(`api` + guid, {
   method: "GET",
   headers: {
    "Accept": "application/octet-stream",
    "Authorization": "Bearer " + token,
   },
   // responseType: 'arraybuffer' //#1 remove this,
})

Instead the response in itself can be passed as arraybuffer as below.

.then((res) => res.arraybuffer())

instead of

.then((res) => res.text())

Now instead of directly using the response to write our pdf file. We can change the data to base64 string and decode it back again to create our pdf file. I used base64ToPdf npm package to handle that.

.then(data => {
  var base64Str = Buffer.from(data).toString('base64');
  base64.base64Decode(base64Str, "file.pdf");
})

I hope this help others. :)

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

7 Comments

what is base64?
It is a npm package link const base64 = require('base64topdf');
@YogeshBhattarai I've just installed base64topdf package, while using base64.base64Decode I'm getting an error with info "fs.writeFileSync is not a function". Had you similar issue?
I did't fix that issue, I've just found another example how to get pdf from response and everything works well.
@spazzola could you please share the example that worked for you?
|
0

    Change res.arraybuffer() to  res.arrayBuffer()

Below is the working code with webdriverio-

  var headers = {
            Authorization: "Bearer " + accessToken,
            Accept: 'application/pdf'
        }
       
           fetch(
                apiurl,
                {
                    headers: {
                        Accept: "application/octet-stream",
                        Authorization: "Bearer " + accessToken
                    },
                },
            )
                .then((res) => {
                    if (!res.ok) {
                        return res.status.toString()
                    }
                    return res.arrayBuffer()
                })
                .then((data) => {
                    var base64Str = Buffer.from(data).toString('base64');
                    base64.base64Decode(base64Str, filename);
                })
                .catch(
                    (err) => {
                        return err.Message;
                    })

    

1 Comment

Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
-2

Here's example which works for me:

async createPdf(context, data) {
    let url = new URL(baseURL + '/invoice/createPdf');
    url.search = new URLSearchParams({
        id: data
    })

    await fetch(url, {
        method: 'GET',
        headers: {
            'Authorization': "Bearer " + localStorage.getItem("jwt"),
            'Accept': 'application/octet-stream'
        },
    }).then((res) => res.arrayBuffer())
        .then(data => {
            var base64Str = Buffer.from(data).toString('base64');

            var binaryString = window.atob(base64Str);
            var binaryLen = binaryString.length;
            var bytes = new Uint8Array(binaryLen);
            for (var i = 0; i < binaryLen; i++) {
                var ascii = binaryString.charCodeAt(i);
                bytes[i] = ascii;
            }
            var arrBuffer = bytes;

            var newBlob = new Blob([arrBuffer], { type: "application/pdf" });

            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveOrOpenBlob(newBlob);
                return;
            }

            data = window.URL.createObjectURL(newBlob);

            var link = document.createElement('a');
            document.body.appendChild(link);
            link.href = data;
            link.download = "Faktura.pdf";
            link.click();
            window.URL.revokeObjectURL(data);
            link.remove();
        })
}

Comments

-2

In my case, the response is same as yours and I'm trying to convert it to a pdf file so that I can preview it on the UI.

For this, I need to fetch the URL already present in the response which is of type blob... to fetch the URL I did URL.createObjectURL(myblob)

const [url,seturl] = useState('');
response
  .then((resp) => resp.blob())
  .then((myBlob) => {
    seturl(URL.createObjectURL(myBlob)); //<-- use this for fetching url from your response
    console.log(myBlob);
  })
  .catch((err) => {
    console.log(err.message());
  });

Comments

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.