The vision: automatic checklists, filled out by simply listening to users explaining what they observe. The architecture of the sample app is based on a lightweight architecture: HTML5, Node.js + the LUIS service in the cloud.

Such an app would be incredibly useful in a hospital, where nurses need to perform and log countless vital sign checks with patients every day.

In part 1 of the article, I’ve explained the overall architecture of the service. In this part, we get hands-on and start implementing the Node.js-based backend. It will ultimately handle all the central messaging. It communicates both with the client user interface running in a browser, as well as the Microsoft LUIS language understanding service in the Azure Cloud.

Creating the Node Backend

Node.js is a great fit for such a service. It’s easy to setup and uses JavaScript for development. Also, the code runs locally for development, allowing rapid testing. But, it’s easy to deploy it to a dedicated server or the cloud later.

Create a folder on your PC (e.g., “vitalsigns-checklist”) and open a PowerShell window. The easiest way is to right-click on the folder name in Windows Explorer while holding the “shift” key on your keyboard. From the popup-window, choose “Open PowerShell window here”.

To initialize the Node.js environment, type:

1

npm init

Enter all the info as you see fit. This sets the app name and other details like the version, license or your name. You can stick with the defaults for everything if you like.

Next, open the folder with Visual Studio Code. Right now, the repository only contains a few files, most importantly the “package.json” that was generated by “npm init”.

Node.js as a Webserver

We’re going to run the service on a web server through Node.js. “Express” is one of the most popular modules that makes it easier to serve web sites from a Node.js environment. Add “Express” to your project from PowerShell through:

1

npm install express

Now, it’s time to create the backend code of our vital signs checklist app. Go to File > New File. Save it under the name you have given the main file when you executed “npm init”. By default, it’s “index.js”. This is the entry JavaScript file that will be executed on the server. Ultimately, it’ll contain most of the logic of our app.

But before we code the cloud-specific code, create a simple test server to see if your installation works:

Finally, run the website from your favorite browser using the following URL:

1

http://127.0.0.1:3000/

Additional Modules

For the client-server communication, we will use the “Socket.IO” module, as it’s more versatile than traditional AJAX.

And finally, the request module simplifies the https request to the language understanding service.

Add both modules to our Node.js app using:

1

2

npm install socket.io

npm install request

Enabling Routing of Files for the User Interface

For the client-side UI, your server will need to provide HTML files, along with images and stylesheets. The best way to do this is to create a folder within your app. Call it “public”.

Next, reconfigure your “index.js” file to serve all the contents of the “public” directory. Instead of the
app.get() line, enter the following:

JavaScript

1

app.use(express.static('public'));

In the newly created “public” folder, create two files: “index.html” and “language.js”. This will be what your users will see when they request the main page from your server. These files will be rendered in the browser of the client.

User Interface: Code and Frameworks

Bootstrap provides great UI templates that make the app look nicer. Essentially, I’ve included it mainly for the pre-built CSS, so that I don’t have to style the app. Additionally, Bootstrap depends on JQuery, which is also helpful for updating the UI with results received from the server.

I decided against using a bigger JavaScript framework (like Angular or React) to minimize the number of new concepts for people not yet too familiar with web development.

The
head is very similar to the bootstrap template. I only added a reference to the “socket.io” library and our own JavaScript file called “language.js”.

The
body is a simple responsive UI, containing two Bootstrap-rows. Each has a single column (-> full width):

The first row contains the form, consisting of:

Text input field with the id “assessment_text”

Submit button

Optional error messagediv (class “errormsg”) below

The second row is a table with the three lines. These will be filled by our backend through the language understanding service: the age, temperature and pupillary response.
As placeholders for the values that will be inserted, each table line has a
span that will be filled with text from our JavaScript code.

JavaScript: Sending Assessments & Showing the Analysis

The JavaScript code of “language.js” is split up into three parts:

Initialization

Sending a textual assessment received from the client to the server

Showing the server’s response in the UI

1. Initialization and Socket.Io Connection

The initialization is short: after the document is loaded, we first make sure the error message is not visible. Then, we initialize a web socket to the server. This will be used for the communication via socket.io.

Initialization of language.js

JavaScript

1

2

3

4

5

6

7

$(document).ready(function(){

console.log("Document ready");

$('.errormsg').hide();

varsocket=io();

// Place the remaining code of this article here...

});

2. Form Submission to the Backend Server

Next, we need to handle the form submission. The most important line of the following code: calling
socket.emit(). This sends the user-entered text to the server, using the message ID “assessment”. The ID is defined by us, and if the server expects a message with the same ID, the communication works.

The rest of the code makes sure the UI is all right:

First, we hide a potentially still visible error message from a previous, failed submission attempt.

Then, we also clear the entered text from the input field “#assessment_text”. This allows the user to immediately start typing the next assessment.

Finally, we use
preventDefault() to make sure the browser doesn’t reload the whole page when the form is submitted. That would be the standard behavior. However, we will dynamically update the page on-the-fly, without ever reloading the whole HTML content.

Sending the entered assessment to the server through socket.io in our language.js file

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

$("#assessment_form").submit(function(e){

// Hide previous error message in case it's still visible

$('.errormsg').hide();

// Retrieve text entered into text box

varenteredText=$("#assessment_text").val();

console.log("Form submitted - entered text: "+enteredText);

// Send the message to the server via socket.io

socket.emit('assessment',enteredText);

// Clear the entered text from the text box

$('#assessment_text').val('');

// Do not reload page

e.preventDefault();

});

3. Handling the Server Response

Finally, we need to handle the response from the server. The JavaScript from our Node.js backend will handle the interaction with the language understanding service. Our front-end JavaScript code only receives and shows pre-processed messages containing the results / or a potential error message.

As we don’t use a JavaScript framework that supports bindings, we directly write the measurement result to the corresponding
span elements in the HTML table.

Only the error message is slightly different – we also ensure the line is visible to the user by calling
show() on the
div.

Handling the analyzed assessment from the language understanding service and updating the UI

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

socket.on('Temperature',function(msg){

$('.result_temperature').html(msg);

});

socket.on('PupillaryResponse',function(msg){

$('.result_pupillaryresponse').html(msg);

});

socket.on('Age',function(msg){

$('.result_age').html(msg);

});

socket.on('Error',function(msg){

$('.errormsg').html(msg);

$('.errormsg').show();

});

The User Interface

That completes the UI. It allows for full user interaction and real-time communication with the backend hosted on a Node.js server. Also, it shows the extracted checklist items from the entered assessment in the appropriate places of the UI.