Passing uint8array to function

1.4k Views Asked by At

I am trying to generate a excel file using fetch api and readable streams. I am trying to pass Uint8Array i am getting from reader.read()and create a buffer object from it and pass it to my writeable stream, but when i pass the array to Buffer.from i get the error

The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object

Below is the relevant part of my code.

I am using node.js & i checked in console the typeof value is Uint8Array

page here is

    const page = await browser.newPage(); //puppeter
let fn = `writeToStream_${Date.now()}`;
await page.exposeFunction(fn, async (body, done) => {
 let buffer = Buffer.from(body);
 await writeStream.write(buffer);
});

const fetchDataResp = await page.evaluate(async (fn, fetchUrl) => {
 const fetchPromise = fetch(fetchUrl);
 const stream = await fetchPromise;
 let reader = stream.body.getReader();
 const decoder = new TextDecoder();
 while(true) {
  const {done, value} = await reader.read();
  if (done){
   break;
  }
  await window[fn](value, false);
 }
 await window[fn]("", true);
},fn,fetchUrl);

what's the correct way to pass Uint8Array?

Thanks.

1

There are 1 best solutions below

3
On

I think this is due to the serialization issue. As stated in the page.evaluate():

If the function passed to the page.evaluate returns a non-Serializable value, then page.evaluate resolves to undefined. DevTools Protocol also supports transferring some additional values that are not serializable by JSON: -0, NaN, Infinity, -Infinity, and bigint literals.

Typed arrays seem serialized as objects:

console.log(JSON.stringify(new Uint8Array([11, 12, 13])));
// {"0":11,"1":12,"2":13}

You can try to transfer typed arrays as common arrays and then re-convert them:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

try {
  const [page] = await browser.pages();

  await page.goto('https://example.org/');

  const data = await page.evaluate(() => {
    return Array.from(new Uint8Array([11, 12, 13]));
  });
  console.log(new Uint8Array(data));
} catch(err) { console.error(err); } finally { await browser.close(); }