2

I'm trying to stream a lot of data from a NodeJS server that fetches the data from Mongo and sends it to React. Since it's quite a lot of data, I've decided to stream it from the server and display it in React as soon as it comes in. Here's a slightly simplified version of what I've got on the server:

const getQuery = async (req, res) => {
const { body } = req;
const query = mongoQueries.buildFindQuery(body);
res.set({ 'Content-Type': 'application/octet-stream' });
Log.find(query).cursor()
  .on('data', (doc) => {
      console.log(doc);
      const data = JSON.stringify(result);
      res.write(`${data}\r\n`);
    }
  })
  .on('end', () => {
    console.log('Data retrieved.');
    res.end();
  });
};

Here's the React part:

fetch(url, {  // this fetch fires the getQuery function on the backend
  method: "POST",
  body: JSON.stringify(object),
  headers: {
    "Content-Type": "application/json",
  }
})
  .then(response => {
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    const pump = () =>
      reader.read().then(({ done, value }) => {
        if (done) return this.postEndHandler();
        console.log(value.length);  // !!!
        const decoded = decoder.decode(value);
        this.display(decoded);
        return pump();
      });
    return pump();
  })
  .catch(err => {
    console.error(err);
    toast.error(err.message);
  });
}

display(chunk) {
  const { data } = this.state;
  try {
    const parsedChunk = chunk.split('\r\n').slice(0, -1);
    parsedChunk.forEach(e => data.push(JSON.parse(e)));
    return this.setState({data});
  } catch (err) {
    throw err;
  }
}

It's a 50/50 whether it completes with no issues or fails at React's side of things. When it fails, it's always because of an incomplete JSON object in parsedChunk.forEach. I did some digging and it turns out that every time it fails, the console.log that I marked with 3 exclamation marks shows 65536. I'm 100% certain it's got something to do with my streams implementation and I'm not queuing the chunks correctly but I'm not sure whether I should be fixing it client or server side. Any help would be greatly appreciated.

  • not sure if this is the right answer, I face the same when I was working with blobs to download PDF from blob. try using this method **https://stackoverflow.com/questions/8022425/getting-blob-data-from-xhr-request** – Shankar Narayanan Jan 07 '19 at 19:40

1 Answers1

0

Instead of implementing your own NDJSON-like streaming JSON protocol which you are basically doing here (with all of the pitfalls of dividing the stream into chunks and packets which is not always under your control), you can take a look at some of the existing tools that are created to do what you need, e.g.:

rsp
  • 107,747
  • 29
  • 201
  • 177