5-minute Signup Forms with Node-RED and Compose

Published

Testing interest in a new startup idea? Looking for a quick and easy way to do RSVPs? Need to capture email addresses for a newsletter? In this article, you'll build a quick and easy signup form in Node-RED that allows users to enter their information and saves entered data to a Compose MongoDB database. We'll also look at validating that data, in this case an email address, and handling validation errors.

Getting Started

To get started, you'll need an installation of Node-RED and to spin up a new Compose MongoDB database with SSL enabled. Check out our previous article on Power Prototyping with MongoDB and Node-RED for a comprehensive setup guide. You can also get started with Node-RED on IBM Bluemix.

Make sure that you've installed the MongoDB2 Node-RED module in whichever version of Node-RED you end up using (see the power prototyping article for instructions on that as well).

Creating the HTTP Routes

We'll need two routes to make any signup form function. The first is a route that displays the HTML for the login form, and the second captures the data sent from the form. Start by dragging two HTTP-IN nodes in Node-RED. Configure the first node with a method of GET and a URL of /signup. You can change this URL at a later time, but you should keep the method the same.

This is the URL that will display our signup form. Now, we'll grab a template node from the palette and drag it onto the canvas. Double-click it, and add the following code to the template area.

<html>  
  <head>
  </head>
  <body>
    <form action="/signup" method="post">
      <h1>Enter your information below to sign up for our newsletter</h1>
      <label for="email">Email Address:</label>
      <input type="text" name="email" />
      <input type="submit" />
    </form>
  </body>
</html>  

This will create a simple form that contains a single field, email. When the user clicks the submit button, the data in the form will be sent to the /signup url, but using the POST method. This is a pretty common pattern, and is easy enough for us to remember.

Let's finish out this flow with an HTTP Response to complete the response.

Now, we can move on to processing the form. In the second HTTP IN node you added, double-click it to configure. In the URL section type /signup and select POST from the Method dropdown. This will be the receiver of the data we sent from our form. We can also add a Debug node to this receiver so we can try out our form and see what kind of data is coming back to us.

Notice that the data is coming back in the msg.payload object. The msg represents the message that we're sending from one node to another, and by convention the payload field will contain any data from that node. The Debug node automatically outputs the msg.payload object since, and shortly we'll look at how we can manipulate other fields in the msg object.

Now, go ahead and fill out the form and click Submit. The first thing you'll notice is that our browser seems to "hang", which means that it's waiting for a response. Since we haven't added an HTTP Response node to the canvas yet, there's no response being sent back to our browser. However, we can still pop on over to Node-RED and check out what our receiver got in the debug panel.

This looks like the data we want to capture, and it's already in JSON format ready for us to send off to MongoDB. Let's go ahead and do that - wire in a MongoDB2 node to save that data in Compose MongoDB. If you haven't done so already, set up a Compose MongoDB database with SSL enabled. Then, configure your MongoDB2 node by double-clicking on it, selecting add new MongoDB2 in the server section, and clicking on the pencil icon to create a new configuration:

Copy your credentials found in the Compose dashboard in the admin section of your database. Once you've configured and clicked save, you should now see your new configuration selected in the server section. Now, put signups in the Collection field, and select insert from the operation dropdown. You can rename Collection to anything you want, and there are a few different options for operation, but for now, these two settings will serve our purposes well.

For now, this will just insert a new document for every signup we receive. We'll look at validating emails shortly, but first let's set up our response page.

When a user has signed up, we'd like to send them to a "thank you" template as a response. Drag a new template node onto the canvas and double-click it to configure. Put the following into the template field:

<html>  
  <head>
  </head>
  <body>
    <h1>Thanks for signing up!</h1>
    <p>You're all set.</p>
  </body>
</html>  

We'll wire up the template to the POST /signup node and send the final output to our HTTP Response node.

Your final flow setup should look like the following:

Load up the signup form and give it a try. Once you've submitted, pop open the Compose dashboard and take a look at the signups collection in your Mongo database. You should be able to see your latest signups.

Adding Simple Email Validation

Now that you have a simple signup form, let's go ahead and make it a little more robust. In this section, we'll demonstrate how to use the node-red-contrib-npm module to use a module from npm without having to download it into node-red ahead of time. In our case, we'll use an email validation library to validate the email field to ensure that the user has entered a valid email.

Install the node-red-contrib-npm module by clicking on the menu in Node-RED and clicking manage palette. Then, select the install tab and type npm. Install the module, and you'll see a new node added to the palette.

Now, we'll use the email-validator npm module to validate our emails. Drag the newly-installed npm node onto the canvas and double-click it to configure. The NPM Module field contains the name of the module we want to use. Since we want to use the email-validator module, type email-validator. Then, in the function field type validate, which is the function within the email-validator that we'd like to use.

Since we access the module code directly by require-ing it, rather than having to use a constructor, we'll set the Module Style field is set to Module Function. We also want the result of the call to our validate method to be sent back to us in the node-red message payload, so set the Message Payload section to Function Return Value. Your settings should look something like the following by the time you're done:

The npm node will now validate any emails we pass into it via the msg.payload object. However, there's a problem. Right now we're sending our form data from node to node via the msg.payload object, but our email validator is only interested in a single text value containing the email we want to validate. Worse still, once the email validator returns back, we'll either have a true or false value in the msg.payload object. It looks like our form data will disappear!

Now to worry - we can work around this by simply moving our signup data over to a different field in the msg object, placing the email in the msg.payload , and then restoring our signup data to the msg.payload once we're sure validation worked.

Let's save off our signup data and update the msg.payload with the email field we want to validate. We'll do that by dragging a function node in between our POST /signup node and our npm node and entering the following code into it:

// Move our signup data to a different part of the msg
msg.signupData = msg.payload;

// Update the msg.payload to contain the email text.
msg.payload = msg.signupData.email;

// Finally, return the entire message object which forwards 
// everything along the chain.
return msg;  

Finalizing the Validation

Now that we have the validator consuming our email and returning a true or false, let's finishing this out by using a switch node to direct our message flow depending on the value of the validation. Start by dragging a switch node onto the canvas and placing it after the npm node. Double-click the switch node and click the +add button on the bottom twice to add two switch channels. For the first channel, select is true from the dropdown, and for the second channel select is false then click done.

The switch node now has two outputs, with the top being followed if the validation is successful and the bottom being followed if validation fails. Drag our thank you template and HTTP Response node to the output side of the switch node and wire the first output to the template. Our flows should now look like the following:

Now, let's handle an invalid email. We'll do this by wiring the second output back over to the template of our signup form. We'll also modify our template to include an error message if the email was invalid. First, we'll the second output of the switch node to a template node that will add an error message on a msg.errorMessage object. Drag a new template node onto the canvas and double-click it to configure. Then, add the following to the template node:

Error: Please enter a valid email.  

Then, we'll wire the output of that template to the input of the signup template. It should look like this:

Finally, let's update the signup template by double-clicking it and replacing its content with the following:

<html>  
  <head>
  </head>
  <body>
  {{ errorMessage }}
    <form action="/signup" method="post">
      <h1>Enter your information below to sign up for our newsletter</h1>
      <label for="email">Email Address:</label>
      <input type="text" name="email" />
      <input type="submit" />
    </form>
  </body>
</html>

The error message will now only be shown if there was an error.

Wrapping Up

When you're just starting up an idea, or trying to gauge interest in a concept, you'll want to be able to capture interest quickly and painlessly. Using Node-RED and MongoDB, we can spin up a simple capture form in a few minutes, and with a few minutes more we can ensure that our form is validated. Stay tuned for more solution-driven articles with Node-RED and Compose in the near future.


If you have any feedback about this or any other Compose article, drop the Compose Articles team a line at articles@compose.com. We're happy to hear from you.

attributionAaron Burden

John O'Connor
John O'Connor is a code junky, educator, and amateur dad that loves letting the smoke out of gadgets, turning caffeine into code, and writing about it all. Love this article? Head over to John O'Connor’s author page to keep reading.

Conquer the Data Layer

Spend your time developing apps, not managing databases.