My web app client hits my Node API which runs a shell script in a child process. The script can take a long time to run, but outputs text along the way. My goal is for my web app to display the progress messages as they are emitted from the child process. After triggering the fetch, my API console is showing the intermittent "write data" logs with text from the child process as expected. However, the Chrome console where I initiate the fetch only displays a single "Received" log with the entire text buffer when the request is complete.
Maybe I'm misunderstanding how this works. Can I actually do what I'm trying to do?
SERVER CODE
app.put('/api/action', (req, res) => {
const spawn = require('child_process').spawn;
const child = spawn('./my-shell-script', [], { cwd: path.resolve(__dirname, '../scripts/'), shell: true });
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Transfer-Encoding', 'chunked');
child.stdout.on('data', data => {
console.log('write data', data.toString());
res.write(data.toString());
});
child.stderr.on('data', error => {
console.log('write error', error.toString());
res.write(error.toString());
});
child.on('error', s => console.error('error', s));
child.on('close', (code) => {
console.log(`action exited with code ${code}`);
if (code !== 0) {
res.status(500);
}
res.end();
});
});
CLIENT CODE
const response = await wpeFetch(`/api/action`, {
method: 'PUT',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify({
scope: site,
action,
})
});
const reader = response.body.pipeThrough(new window.TextDecoderStream()).getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log('Received', value);
}
console.log('Response fully received');