CUR
CUR

Reputation: 31

Execute a Node.js child process after clicking a button

At the moment I have a code in Node.js which calls the program "EnergyPlus". Unfortunately I have to start an external console and execute the Node.js file "manually". However, I would like to be able to press a button in the front end of my application that starts the "EnergyPlus" plus program.

Here is my Node.js file:

var spawn = require('child_process').spawn,
child = spawn('C:\\EnergyPlusV9-0-1\\EP-Launch.exe', ["C:/Windows/System32/Drivers/etc/hosts"]);

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

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

child.on('close', function (code) {
    console.log('child process exited with code ' + code);
});

Is there a way to integrate this code within a button or to execute this code after clicking a button? Thank you very much in advance!

Upvotes: -3

Views: 3702

Answers (2)

CUR
CUR

Reputation: 31

Thank you very much for the help! I have found the solution for my problem. To start from the beginning, within my application I work with React and Webpack. To solve my problem, I structured my Server.js file (where I set up the Express behavior) in the following way:

const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
const fs = require("fs")
const spawn = require('child_process').spawn;

// console.log that your server is up and running
app.listen(port, () => console.log(`Listening on port ${port}`));
app.use(cors())

// create a GET route
app.get('/express_backend/:filename', (body, res) => {
const f = body.params.filename;

// open EnergyPlus Programm with a specific file which is stored localy
let child = spawn(
'C:\\EnergyPlusV9-0-1\\EP-Launch.exe',
 [process.cwd()+"src/"+ f + ".idf"]
 );

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

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

child.on('close', function (code) {
console.log('child process exited with code ' + code);
});

res.send('EnergyPlus is running');
});

// default options
app.use(fileUpload());

//post the uploaded file into the local storage
app.post('/upload', function(req, res) {
  ...
}

// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let sampleFile = req.files.file;

// Use the mv() method to place the file localy
 fs.writeFile(__dirname + `/upload/${sampleFile.name}`, sampleFile.data,
(err) => {
   ....
  })
});

Like Nino Filiu mentioned in his post, I integrated the child spawn function into the server.js. First, I call the EP launch.ex with the specific file, I stored localy (this function is not part of this answer). "C:\EnergyPlusV9-0-1\EP-Launch.exe"is the path to EnergyPlus. "[process.cwd()+"src/"+ f + ".idf"]" helps EnergyPlus to open the local stored fiel directl. So the important thing regarding my problem was the app.get, which I trigger within my App.js. In App.js I call the spawn child process like this:

class App extends Component { 

constructor(props){
super(props)
this.state = {filename: null}
};

componentDidMount() {
  ...
};

callBackendAPI = async () => {
  ...
};

//trigger the spawn child function within server.js
startEnergyPlus = (e) =>{
fetch (`http://localhost:5000/express_backend/${this.state.filename}`, {
method: "GET"
});

render(){
 return( 
  <div className="App">
   <button onClick={this.startEnergyPlus}>start app</button>
  </div>
};

And that is it. Hopefully, it is clear and helpfull. If not, please leave a comment!

Upvotes: 0

Nino Filiu
Nino Filiu

Reputation: 18541

Here's how you can do this:

  1. On client side button click, make a request to a certain path in your express API
  2. Your express API handles the request by launching the program

Code something that looks like this:

client.html:

<button onclick="func()">start app</button>
<script>
  const func = () => fetch('http://your.api.url/some/path');
</script>

server.js:

// imports
const express = require('express');
const spawn = require('child_process').spawn;

// create server
const app = express();

// upon request to the launch path, launch the program
app.get('/some/path', (req, res) => {

  let child = spawn(
    'C:\\EnergyPlusV9-0-1\\EP-Launch.exe',
    ["C:/Windows/System32/Drivers/etc/hosts"]
  );
  // etc (rest of the code you wrote)

  // response. You can modify this to send a custom response to your client
  res.send('');
})

Upvotes: 1

Related Questions