Working with Site Data in Node.js

  • 4/1/2015
In this chapter from Node.js for .NET Developers, David Gaynes explains how to work with data from URLs, data from users, and data from external sources in node.js.

Data comes in many shapes and sizes. It can come from within your application as it works, from users, or from outside data stores. As with the rest of Node.js, there is an npm package to deal individually with each of the myriad ways data might be provided to your application.

In general, this data can be broken into three major categories, with each having a couple of primary ways that data would likely come to you:

  • Data from URLs

    • Route/Path pattern
    • QueryString
  • Data from users

    • Form posts
    • Field input
  • Data from external sources

    • Databases (covered in Chapter 6, “Working with external data in Node.js”)
    • File systems (covered in Chapter 7, “Working with file data in Node.js”)

We’ll walk through these and incorporate them into your Node.js application.

Data from URLs

The first way you’ll have to deal with data in the application relates to data that comes in the URL. Even our simple example code for rendering an array that isn’t connected to anything contains within it the idea that we will drill down into some detail about some item on the list. And that item is specified within the URL.

In this case, as shown, we opted to build a path that looks like this:

href= 'details/<%= players[i].id%>'>

This path yields the following result or similar as the URL path:

'details/5'

You could keep going and add as many path arguments as you like after the original. Each argument is given a name when you declare the path, like this:

router.get('/details/:id')

Or by adding to it, like this:

router.get('/details/:id/:name')

Then, in code, these arguments are accessed through the param collection provided by Express:

req.param("id")

Your get will look like this:

router.get('/details/:id', function (req, res) { 
   res.render('details', { 
      playerId: req.param("id") 
   });
});

When you create your player and then set up the details.js/.ejs view, you’ll have a playerId argument to get your hands on and display right away to make sure you have the correct data.

Always remember, as I mentioned earlier, that you must order your code to go from most specific in the path to least specific because the engine will render the first matching pattern that it finds. The warning here is this URL coming in as a web request:

http://127.0.0.1:1234/details/1/Payton

This will match the following route:

router.get('/details')

And it will match this route as well:

router.get('/details/:id')

And this route:

router.get('/details/:id/:name')

The second and third routes will never be reached if these are in the wrong order in your code file. To be properly done, these route entries need to be exactly reversed from what is shown here.

Pulling arguments from structured route paths is one way to pass and pull data from the URL. As an alternative, you could have placed the data into a QueryString. In the real world, this is equally as likely to be the pattern you choose to follow for building URLs internally to pass data.

You use the QueryString collection to access the URL’s name/value pairs either by index or by name. In general, it will be just as easy to code a solution that parses its data as with the param collection. That being said, it is your choice, and each option works at least equally well.

To implement access to the QueryString, simply reference its collection instead of the param collection:

req.query.ID

In this case, as you see, you can actually use dot notation to access the individually named members of the collection you specified. The processing engine recognizes the question mark (?) as the beginning of the collection and the ampersand (&) as the argument separator. Thus, the route itself is still the same as the base route and the previously mentioned issues with route order in the file are not relevant.

So to process this URL:

http://127.0.0.1:1234/details?ID=1&Name=Payton

the route get function to render this data in all cases would simply be

router.get('/details', function (req, res) {
    res.render('details', {
playerId: req.query.ID,
name: req.query.Name 
   });
});

As you can see, you simply take apart the arguments by name one at a time to get to the values contained in them. Passing an entire object this way would be done by manually taking apart the object properties to provide the necessary arguments in your assembled link to the details page:

href= 'details?ID=<%= players[i].id%>&Name=<%= players[i].lastName%>'>

Continue on like this in as much depth as required. In real-world practice, this approach is rarely needed for sending information to your own .ejs files. This is because, as you have seen, you can pass entire objects or even collections of objects in this way:

res.render('survey', {
    players: arrPlayers
        });

For connecting to external resources and assembling a QueryString or a route, or for taking in connections to your resources from others and thus parsing an inbound QueryString or route, working with data directly inside the URL is often your only option for moving that data from place to place.