0
votes

I'm getting error cannot set headers on express js, I think the problem is have to write setHeader, i was set but stil can't, this my code:

router.get('/cek', (req, res) => {
const child = execFile(commandd, ['-c', 'config', 'GSM.Radio.C0']);
child.stdout.on('data', 
    function (data) {
        value = (JSON.stringify(data));
        x = value.split('.');
        y = JSON.stringify(x[2])
        result = y.replace(/\D/g, "");
        res.setHeader('Content-Type', 'text/html');
        res.send(result);
    }
);

child.stderr.on('data',
    function (data) {
        console.log('err data: ' + data);
    }
);

});

I tired to fixing this error for two days, but still cannot, anybody can help?

1
The data event will fire multiple times, yielding one chunk of the text from stdout at a time. You seem to be treating it as though it'll pass all the text in one go. Assuming there is relatively little text you can concatenate all the chunks in data events and then send it on the close event. Other approaches are available depending on the specifics. - skirtle
This error tipically occurs when you try to do something after a res.send method has been called. You could try to add two things: 1) a return before res.send, so the request of /cek would be blocking, 2) add a res.send(err) on stderr. In both cases something could trigger your mistake - Federico Ibba
thank you @FedericoIbba, answer in the below that's works.. - idnsa info

1 Answers

0
votes

As stated by Frederico Ibba, this is usually caused after res.send is sent and there is still data being processed... Your workaround for this may simply be to receive all the data before sending it out using res.send. You can try this.

async function executeCommand() {
    return new Promise((resolve, reject) => {
        const child = execFile(commandd, ['-c', 'config', 'GSM.Radio.C0']);

        child.stdout.on('data', 
             function (data) {
                value = (JSON.stringify(data));
                x = value.split('.');
                y = JSON.stringify(x[2])
                result = y.replace(/\D/g, "");

                resolve(result);
             }
        );

        child.stderr.on('data',
           function (err) { // Renamed data for err for clarification
               reject(err);
           }
        );
    });
}

router.get('/url', async (req, res) => {
    try {
        const result = await executeCommand();
        res.setHeader('Content-Type', 'text/html');
        res.send(result);
    } catch(error) {
        // There was an error. I'm throwing a 500
        res.sendStatus(500);
    }
});

Note that this will be effective only if you are confident that the data is being fired once, as indicated by skirtle