Skip to content
Robyn Overstreet edited this page Mar 5, 2015 · 3 revisions

Using Servi.js

Routing

In servi, we can set up the URLs our application will use. This is called routing. In servi, you set the name of the URL, or route, and then the name of a function to run when that URL is visited.

route('/one',handleOne);
route('/two',handleTwo);
route('/buckle/my/shoe',buckleMyShoe);
		
function handleOne(request) {
    console.log("one");
    request.respond("thanks one");
}			

function handleTwo(request) {
    console.log("two");
    request.respond("thanks two");
}

function buckleMyShoe(request) {
    console.log("buckle my shoe");
    request.respond("buckle my shoe");
}

Each function called in route takes a request parameter, which contains information about the user's request and lets you respond to the request, using the .respond() method.

The exciting part comes when the route handler can take in additional information and give a customized response based on that information.

route('/profile/:username',showProfile);

function showProfile(request){
    request.respond("All about " + request.params.username);
}

Define a variable in a route by using a colon (:) in front of the variable name. Then retrieve the value of the variable from the request object using request.params.VARIABLE_NAME.

See the following scripts in the repo for examples using parameter variables:

Forms

#####The query string In addition to accessing variables you set up in route(), the request.params object will also contain any data that comes in through the query string in the URL. You've seen examples of the query string in some of the external APIs we used. For example, the Instagram API uses the query string in its URL to set the client id and the latitude/longitude in a location search: https://api.instagram.com/v1/media/search?lat=48.858844&lng=2.294351&client_id=abc123abc12345.

In servi, the URL mysite.com/info/person?city=Brooklyn&name=Jim&school=NYU would provide the variables city,name, and school as request.params.city, request.params.name, etc.

#####GET Forms can be used to create query strings. When a form uses the method is GET, the content will show up in the URL submitted to the server.

<form method="GET" action="/somescript">
    <input type="text" name="name" value="Your Name">
    <input type="text" name="city" value="Your City">
    <input type="submit" name="submit" value="Submit">
</form>

When a form is submitted using the GET method, the browser goes to the URL set in the "action" attribute and tacks on the form values in the query string. The form above, when submitted with the values "Jane" and "Brooklyn", would go to the url whateversite.com/somescript?name=Jane&city=Brooklyn&submit=Submit.

In Servi, we can access the data with:

route('/somescript',handleQuery);

function handleQuery(request){
    var response = "The name submitted was: " + request.params.name + "\n";
    response += "The city submitted was: " + request.params.city;
    request.respond(response);
}

See the following folder in the repo for a form example using GET: https://github.com/robynitp/networkedmedia/tree/master/week6/03-servi-form-get

POST

If we change the form "method" to "POST" the content is sent in a manner that we can't see in the URL. You would use this method for information that shouldn't be submitted more than once (such as entering a comment) or that shouldn't be visible in the URL such as username/password:

<form method="POST" action="/somescript">
	<input type="text" name="name" value="Your Name">
	<input type="text" name="city" value="Your City">
	<input type="submit" name="submit" value="Submit">
</form>

In Servi, the data in a POST query comes in via the request.fields object:

route('/somescript',handleQuery);

function handleQuery(request){
    var response = "The name submitted was: " + request.fields.name + "\n";
    response += "The city submitted was: " + request.fields.city;
    request.respond(response);
}		

See the following folder in the repo for a form example using POST: https://github.com/robynitp/networkedmedia/tree/master/week6/04-servi-form-post

The Servi database

####Saving Data

Servi has a built in database which uses JSON. (For the record, it uses NeDB, a node database library).

// Create or use the existing database
var infoDB = useDatabase("namescities");

route('/somescript',handleQuery);

function handleQuery(request)
{
	// request.params.name
	// request.params.city
	var response = "The name submitted was: " + request.fields.name + "\n";
	response += "The city submitted was: " + request.fields.city;
	
	// Create a JSON object to hold the data
	var dataToSave = {name: request.fields.name, city: request.fields.city};
	
	// Save the data to the database
	infoDB.add(dataToSave);
	
	request.respond(response);
}

####Retrieving Data

To pull data out of the database:

// Create or use the existing database
var infoDB = useDatabase("namescities");

route('/viewdata',viewData);

function viewData(request) {
	infoDB.getAll(gotData);    

	function gotData(theData) {
		var response = "";
		for (i = 0; i < theData.length; i++) {
			response += theData[i].name + " lives in " + theData.city + "\n";
		}
		request.respond(response);
	}
}

See this Servi database example in the repo: https://github.com/robynitp/networkedmedia/blob/master/week6/08-servi-db/server.js

For more info on using the Servi database, see the Servi documentation.

Templating

When you want to create an HTML page once and use it as template for different pieces of data, as in the user profile example above, Servi provides the render() function. By default, Servi uses the EJS template rendering system. Check out the EJS documentation for more complete details.

The render() function takes two parameters: the HTML template, and an object containing the data that will go into the template.

var mydata = {
    title: "Things You Never Knew",
    date: "November 24, 2014",
    articleText: "Donec diam nibh, imperdiet ac lacus sit amet, accumsan tincidunt urna."
}
request.render("mytemplate.html",mydata);

In the HTML template, create placeholders for the data, using the same names as the properties of the object -- in this example, we have title, date, and articleText. So the HTML template might look like:

<html>
 <head>
    <title><%= title %></title>
 </head>
 <body>
    <h1>New York Daily News</h1>

    <h2><%= title %></h2>
    <h3><%= date %></h3>
    <p><%= articleText %></p>  
 </body>
</html>

If a template variable contains an array or object, you can use a loop to iterate over elements. For example, the object below contains an array called people:

var data = {
	people: [
	    {
	        "name": "Brad",
	        "city": "London"
	    },
	    {
	        "name": "Jill",	
	        "city": "Tokyo"
	    },
	    {
	        "name": "Kate",
	        "city": "New York"
	    }
	]
};

Then, using request.render("my_template.html",data);, you could hook it up to a template that contained a loop, like this:

<h1>Where people live</h1>
<!-- Embed a loop in the template tags -->
<% for (i = 0; i < people.length; i++) { %>
        
    <li><%= people[i].name %> lives in <%= people[i].city %></li>

<% } %> <!-- end the for loop -->

See these template examples in the repo:

#####More Servi documentation See the Servi.js github wiki for more documentation.