Ryan H
Ryan H

Reputation: 13

node.js serialport cannot pass variable outside SerialPort.list function

I am trying to get the COM port of my device at runtime using the node.js serialport module.

const SerialPort = require('serialport');
var fs = require('fs');

var serialVar = getSerialPort();

console.log("outer: "+serialVar);

function getSerialPort() 
{
    SerialPort.list(function (err, ports) {
        ports.forEach(function(port) {
            if (port.pnpId == "USB\\VID_0451&PID_BEF3&MI_00\\6&808E38E&0&0000") {
                console.log("inner: "+port.comName);
                return port.comName;
            } 
        });
    });
}

output:

outer: undefined
inner: COM8

From the output, it appears that getSerialPort() finishes after everything else in the script has run rather than running in it's entirety before continuing past the point it was called. I'm not sure why this is.

I have tried several variations of this such as:

const SerialPort = require('serialport');
var fs = require('fs');

var serialVar = {};
getSerialPort();

console.log("outer: "+serialVar.port);
function getSerialPort() 
{
    SerialPort.list(function (err, ports) {
        ports.forEach(function(port) {
            if (port.pnpId == "USB\\VID_0451&PID_BEF3&MI_00\\6&808E38E&0&0000") {
                serialVar.port = port.comName;
                console.log("inner: "+serialVar.port);
            }
        });
    });
}

with no change.

Upvotes: 0

Views: 1384

Answers (1)

ktilcu
ktilcu

Reputation: 3128

Javascript is inherently asynchronous. What is happening is that the console.log is executing before the serial ports can be listed. The library provides a callback (which you are using) and a promise. Either of these can be used to make sure things run in order. I recommend promises.

const SerialPort = require('serialport');

SerialPort.list() // returns promise that resolves to list of ports
    // filters for a specific port
    .then(ports => ports.filter(port => port.pnpId == "USB\\VID_0451&PID_BEF3&MI_00\\6&808E38E&0&0000"))
    // logs info
    .then(ports => {console.log('inner',port[0].comName, 'outer', port[0]); return ports})

Upvotes: 1

Related Questions