krt krt - 4 months ago 17
Javascript Question

Style output from a nodeJS child_process in html

I have just starting learning nodeJS and now I have some trouble understanding how I can style the output from a child_process in html/css.

This far I have the following code:

#!/usr/local/bin/node

var express = require('express');
var app = express();
var fs = require('fs');
var govSh = './../sh/govc.sh';
var util = require('util');
var spawn = require('child_process').spawn;
var PORT = 3333;

if (!fs.existsSync(govSh)) {
console.log("can't find govc script");
process.exit(1);
};
app.get('/vmlist', function(req, res) {
var invPath = spawn(govSh, ['vmlist']);
invPath.stdout.pipe(res);
});

app.listen(PORT, function() {
console.log("app will listen on port 3333");
});


And when I do a reuest to
http://127.0.0.1:3333/vmlist
I get presented with this in the browser:

{"name":"centos1", "state":"poweredOff", "ram":"1", "vcpu":"1", "ip4":""}
{"name":"centos2", "state":"poweredOff", "ram":"8", "vcpu":"2", "ip4":""}


How is it possible for me to use this in html and style it with css? Or how can I send it to a client side jQuery / Ajax?

EDIT:

As it looks now, the govc.sh script will output like above. But this is not a requirement for me, i just want to use the output in html and style it. In the govc.sh script it's with printf i output the info with a for loop:

printf '{"name":"%s", "state":"%s", "ram":"%s", "vcpu":"%s", "ip4":"%s"}\n' ${name} ${vmState} ${vmRam} ${vmCpu} ${vmIp4}


I can change this if it makes things easier in nodejs/javasript.

Answer

To render as normal page You've to use ejs, jade templating or output html file (like in this example) and then call api from outputted html using jquery or etc.

Server-side code example

var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var util = require('util');
var execFile = require('child_process').execFile;
var PORT = 3333;

app.use('/assets', express.static('assets')); // create folder "static" relative to this app file and put Your css, js files inside assets

// put index.html file to relative to this file
app.route('/')
  .all(function(req, res) {
    res.sendFile(path.join(__dirname, 'index.html'));
  });

app.route('/vmlist') 
    .get(function(req, res) {
      execFile('./../sh/govc.sh', ['vmlist'], function(err, output) {
          if (err) {
            return res.status(500).send(err);
          }

          // I saw in Your question that application returns 2 json objects 
          // that are an object per line without object delimiter 
          // and array [] chars that will not well handled, 
          // so I'm recreating proper json objects array 
          output = output.split("\n");
          var response = [];
          for(var o in output) {
            var line = output[0].replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); // trimming
            if(line != '') {
              response.push(JSON.parse(line));
            }
          }

          res.json(response); // responding with application/json headers and json objects in it
      });
    });

app.listen(PORT, function() {
    console.log("app will listen on port 3333");
});

Client-side (index.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="/assets/css/common.css">
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script>
      $(function() {
        function getVMS() {
          $.get('http://127.0.0.1:3333/vmlist',  {},  function(vms) {
            var html = '';
            for(var v in vms) {
              var vm = vms[v];
              html+= '<div class="cpu">';
              html+= 'Name: '+vm.name+'<br/>';
              html+= 'State: '+vm.state+'<br/>';
              html+= 'RAM: '+vm.ram+'<br/>';
              html+= 'IPv4: '+vm.ip4+'<br/>';
              html+= '</div>';
            }

            $('#vmlist').html(html);
          });
        }

        getVMS(); // initially getting VMS
        setInterval(getVMS, 10000); // getting VMS continuously every 10 second 
      });
    </script>
</head>
<body>

  <div id="vmlist"></div>

</body>
</html>



File structure:
enter image description here

P.S. There may be issue with properly responding from vmlist (because output formatting). if it will not work please execute "govc.sh" from console and give me output of it in comment.

Comments