python in Node.js using spawn don't have response

Viewed 225

I am new to spawn and I try to get the user's input from my frontend to my Node.js and then pass it to my python sentiment analysis code. But when I try to use spawn to get access to my python, it didn't response. I very much appreciate your help. Thank you.

Here what I want to do is passing the json data from the frontend to /add function via Axio.

const router = require('express').Router();
let inputData = require('../models/inputData.model');
const spawn = require("child_process").spawn;

router.route('/add').post((req, res) => {
const sentence = req.body.sentence;

const newData = new inputData({sentence});

const pythonProcess = spawn('python3', ['C:\\Users\\70519\\PycharmProjects\\pythonProject\\pythonserver.py', newData])

pythonProcess.stdout.on('data', (data) => {
    res.json('I am here!')
    res.json(data.toString());
})
});

However, in my website console, I don't receive 'I am here' from res.json(). Is that mean my python code is not running?

1 Answers

I see in your current code that you are handling an async behavior inside a synchronous function. You call on the on event, but you are not "waiting" for it to occur.

When you call the on event, you are setting a callback function called when the data from the spawn process is available. The problem is that the function has finished its execution before processing the callback call.

ExpressJS offers many ways to handle asynchronous procedures. I suggest you use Promises to solve your current situation. Check this example on how to use them with Express:

const { spawn } = require('child_process')
const express = require('express')

const PORT = 3000

const app = express()

app.get('/', (req, res, next) => {
  // The command arguments are passed as an array of strings.
  const ls = spawn('ls', ['-lh', '/tmp'])

  new Promise((resolve, reject) => {
    // Listen to the `data` event on `stdout`.
    ls.stdout.on('data', (data) => resolve(`stdout: ${data}`))
    // Listen to the `data` event on `srderr`.
    ls.stderr.on('data', (data) => reject(`stdout: ${data}`))
  })
    .then((data) => {
      res.status(200).send(data)
      next()
    })
    .catch((err) => next(err))
})

app.use((err, req, res, next) => {
  console.log(err.message)
  console.error(err.stack)
  res.status(500).send({error: err.message})
})

app.listen(PORT, () => console.log(`listening on port ${PORT}`))

Also, you should check out Express`s middleware* documentation to find more information on how they work.

*: middleware is the name Express gives to functions that receive the request, response objects, and next function.

Related