As with other MVC-based frameworks, you use models to get data although Mojito allows
controllers to directly fetch content as well. Thus far, our applications have been
just getting static data from the model, but in this module we’re going to learn how
to get data in a couple of different ways. The recommended way in Mojito is to use YQL, an
SQL-like language and Web Service that allows you to make queries on Web data. You can
also use the REST module that comes with Mojito to make HTTP calls to Web services.

We’re going to use YQL to get GitHub data into our application, but we’ll present an example
of how to use the Y.mojito.lib.REST Class to
make REST calls. We’re going to add another mojit to get Twitter data with the help of the
Node.js module simple-twitter.

In the last module, we discussed composite mojits, showing how to
configure the parent-child relationship between mojits and then use
the Composite addon to execute child mojits. Using composite mojits,
we were able to create a page layout and add content to the body of
the HTML page. We also kept our frame mojit to create the HTML page
for use. In summary, we covered the following:

Mojito separates the data layer with models that can use the Mojito REST library or YQL.
In most cases, we recommend YQL because you can have a consistent API to get data from
different sources and can filter results with YQL statements. The response that is
returned from YQL is also more consistent regardless of the data sources, making it
easier to parse. The YQL Web Service is also optimized to get data to you faster, and
YUI has a handy YQL module that makes using YQL even easier. We’re going to provide an
overview of YQL, show you how to form YQL statements, and finally how to use YUI’s
YQL Query module.

We briefly went over the structure of models in the Mojits module when we discussed mojit
MVC. Mojito models, like controllers, are just YUI modules, but use a different namespace
than controllers. With that in mind, let’s just summarize some of the important points
about mojit models.

The file name of a model has two parts. The model name and the affinity. The model name
is an arbitrary string, and the affinity, as we have said before, indicates where the code
is running. The affinity may be server, client, or common, where common
indicates the code can run on either the server or client. Thus, the syntax of the model
file name is the following: {model_name}.{affinity}.js

Models like controllers are registered with YUI as modules with YUI.add, have their own
namespace, and list dependencies in the requires array.

Below is the skeleton of the model. Notice that we have required the yql module.
This is the main way for getting data. If you haven’t heard of or used YQL before,
don’t worry, we’ll give you a little primer before writing code to get data with
YQL in the next section.

YUI.add('yql',function(Y,NAME){// The namespace for the model that passes the// nameY.mojito.models[NAME]={init:function(config){this.config=config;},getData:function(params,callback){// Model function to get data...},...};},'0.0.1',{requires:['yql']});

If you know SQL, then think of YQL as SQL for the Internet, with the Internet
representing a MySQL database. In reality, Internet data can only be fetched
by the YQL Web Service if there is a table that defines how data is accessed.
YQL comes with a wide range of built-in tables, and the developer community has
contributed YQL Open Data Tables (ODT) as well. The table tells YQL how to
get the Web data, and the YQL statement (like an SQL query) tells YQL what
data to get from that table and how to filter that data. If you have questions,
take a look at the YQL Guide.

The YQL language, like SQL, has many verbs for reading and writing data. For
our application, we’ll be just reading data with the SELECT verb. To filter data,
like SQL, you use the key word WHERE. YQL also includes operators such as LIKE
for filtering, the key word LIMIT to limit the number of results, and the
pipe (|) to filter results through a function such as SORT. We can’t possibly
cover all of the features of YQL here, but an example YQL statement can
certainly show you many of the features that we’ve just discussed:

To use YQL, you make an HTTP request to the YQL Web Service. You use one of
the YQL Web Service URLs and append the YQL statement to the query parameter q.
The YQL Web Service has a couple URLs for getting public and authorized data:

So, if you wanted to make the query select*fromlocal.searchwherequery=”pizza”,
you would make an HTTP GET call to the following URL:
http://query.yahooapis.com/v1/public/yql?q=select*fromlocal.searchwherequery=”pizza”

Fortunately, YUI’s YQL module forms the URL and makes the call for you, so you
just need to form the YQL statement. With that being said, let’s look at the YQL module.

To use the YQL Query module in a mojit model, you simply add the string "yql"
to the requires array as shown below:

},'0.0.1',{requires:['yql']});

To use the module, you form the YQL statement using an existing table or a table that you
have created and are hosting and then pass that statement and a callback function
to Y.YQL. The yql module will make the REST call to the YQL Web service using
the passed statement and your results will be returned to the callback.

In our application, we’ll be using YQL to get GitHub statistics. In the getData method
of our model shown below, we’re using a custom table (thus, the use statement) that is
appropos hosted on GitHub. The results are handled by the method onDataReturn.

getData:function(params,callback){varyqlTable='https://raw.github.com/triptych/trib/master/src/yql/github.xml',query="use '{table}' as yahoo.awooldri.github.repo; select watchers,forks from yahoo.awooldri.github.repo where id='yql' and repo='yql-tables'",queryParams={table:yqlTable},cookedQuery=Y.substitute(query,queryParams);Y.YQL(cookedQuery,Y.bind(this.onDataReturn,this,callback));},onDataReturn:function(cb,result){Y.log("onDataReturn called");if(typeofresult.error==='undefined'){varresults=result.query.results.json;cb(results);}else{cb(result.error);}}

The REST module
for Mojito provides an easy make HTTP calls to Web services

To use the module, you add the string "mojito-rest-lib" to the requires array as
shown below.

},'0.0.1',{requires:['mojito-rest-lib']});

The REST module allows you to make HTTP GET, HEAD, PUT, POST, and DELETE calls.
The methods of the module all take the following parameters:

url - The URL to make the HTTP call to.

params - The parameters to add to the request.

config - Configurations for the call, such as headers or timeout values.

callback - The function that receives the response or error.

Using the REST module, the HTTP calls have the following syntax:

Y.mojito.lib.REST.{HTTP_VERB}}(uri,params,config,callback)

We won’t be using the REST module in this application because the Twitter Search API
requires OAuth authorization, which is done more easily through a library such as
simple-twitter. We’re going to just show you a simple example of using the REST
module for your future reference.

In the getData method below, we pass our
parameters to make the call to the Y! Groups page and return the JSON parsed results back
with the callback.

After you have your OAuth keys and installed simple-twitter, you can use
that module in your model to get Twitter data. Because Mojito runs on Node.js,
you can use just about any npm module using the require method, which is what
we’re going to do in the Twitter model.

To help explain the model code, let’s first just take a look at how
to use the simple-twitter module. You require the module and save a reference
to a variable. With that reference, you can instantiate an object with your
Twitter OAuth keys that will allow you to make a REST call to their APIs.

The controller brokers all requests, calling the model, and passing data back
to the client or rendering templates with the data. The controller accesses and uses
models much like it uses addons.

The controller needs to require the Models addon and use the method get from
that addon to access a model. For example, for the controller shown below
to get the model with the file name twitter.{affinity}.{selector}.js, the Models addon
is required and then used to access and use the the model. In our application,
the file will be twitter.server.js, but you could have a version for the
client that uses the affinity client or you could have a model with a
different selector that is chosen based on the context, which we’ll learn
about in 9. Handlebars, Templates, and Custom Views,
when we use selectors to choose the appropriate template for a client, such
as an iPhone template or an Android template.

After you have copied the application that you made in the last module
(see Setting Up), change into the application 05_getting_data.

Let’s create the Twitter mojit that get Twitter data for us.

$mojitocreatemojitTwitter

Change to the models directory of Twitter. We’re going to deal with
getting Twitter data first.

Rename the file model.server.js to twitter.server.js and then change the
registered module name from twitter-model to twittersearch-model.

Open twitter.server.js in an editor, and modify the method getData, so
that it looks like the snippet below. As you can see, we use the simple-twitter
module to make the REST calls to the Twitter Search API. We’ve also added mocked
data for those who don’t want to open a Twitter developer account and get OAuth keys.

getData:function(count,q,oauth,cb){// Confirm OAuth keys have been passed// You'll also need to add `simple-twitter: "~1.0.0"` to the `dependencies` object in// `package.json` and then run `npm install` from the application directory// to get the `simple-twitter` module that will call the Twitter Search API// If `oauth` is null, you'll be using the mocked data.Y.log(oauth,"info",NAME);if(oauth){vartwitter=require('simple-twitter'),tweets=newtwitter(oauth.consumer_key,oauth.consumer_secret,oauth.access_token_key,oauth.access_token_secret);tweets.get("search/tweets","?q="+encodeURIComponent(q)+"&count="+count,function(error,data){if(error){returncb(error);}cb(null,Y.JSON.parse(data));});// Use mock data if no OAuth keys have been provided}else{varmock_yui_data={statuses:[{from_user:"YUI User 1",text:"Love the new YUI Pure!"},{from_user:"YUI User 2",text:"YUI Charts is off the charts!"},{from_user:"YUI User 3",text:"Mojito + YUI = developer goodness."},{from_user:"YUI User 4",text:"The YUI Gallery offers all kinds of cool modules!"},{from_user:"YUI User 5",text:"I'm anxious to try the YUI App Framework."}]};varmock_mojito_data={statuses:[{from_user:"Mojit User 1",text:"Mojits are self-contained MVC modules."},{from_user:"Mojito User 2",text:"The Data addon allows you to rehydrate data on the client!"},{from_user:"Mojito User 3",text:"Mojito + YUI = developer goodness."},{from_user:"Mojito User 4",text:"Mojito makes it easier to create pages for different devices."},{from_user:"Mojito User 5",text:"The Mojito CLI is now a separate package from Mojito."}]};if("@yuilibrary"==q){cb(null,mock_yui_data);}else{cb(null,mock_mojito_data);}}}

We also need to add the dependencies to use the REST and JSON modules:

},'0.0.1',{requires:['mojito','mojito-rest-lib','json']});

We need to modify the controller to use the model twitter.server.js.
Open mojits/Twitter/controller.server.js in an editor,
modify the index method so that it’s the same as that shown below.
Make sure that the Models and Assets addon are required as well. The Models
addon allows you to access our model and call the model function getData.

Let’s turn our attention to the Github mojit. We have been waiting long
enough to get GitHub data, but before we change any code, let’s rename
the model file to yql.server.js. Now we can edit the file yql.server.js.
Open the file in an editor, change the module name to stats-model-yql, update
the getData function with the code below. Notice that we are using the YQL
Open Data Table github.xml, which YQL allows you to use with the use
statement.

Besides the YQL module, we also used the Substitute module, so make
sure to add both of those modules to the requires array:

},'0.0.1',{requires:['yql','substitute']});

The Github controller needs to get the correct model. We’re also
going to simplify the index function to only use the default template and
add the mojito-assets-addon to the requires array.
Modify the index function and the requires array so that they are the same
as that below.

Because the Github mojit displays a title for the GitHub statistics. Let’s remove
the title property passed to ac.composite.done in Body/controller.server.js
and the {{title}} Handlebars expression in the template
Body/views/index.hb.html so they look like the following:

Okay, we have Github mojit getting real data and even have a mojit
for getting Twitter data. Did we forget anything? Yeah, we need to
plug our Twitter mojit into the body by making it a child of the
body instance. Let’s update the body instance in the application.json:

We’re going to need to update the path to our assets, but before we do that, let’s
update the CSS file. Replace the contents of assets/trib.css with the following
and then update the path in application.json to static/05_getting_data/assets/trib.css:

You can go ahead and start the application. You’ll see both real-time
data for GitHub and Twitter. We’ll be adding more mojits with more
data in the coming modules, so you may want to review the sections on YQL.

If you can access your model, but can’t call a method in your model, you either
tried to access a model (module) that doesn’t exist or a method that doesn’t exist.
Make sure that the {model_name} in the expression ac.models.get({model_name});
is correct and that the method exists. The {{model_name}} is the prefix of the
model file name: {{model_name}}.{{affinity}}.{{selector}}

Currently, no. You push data to the client to initially render the page, but thereafter,
binders or new HTTP requests only can get new data. We’ll see how to use binders to request
new data in 7. Mojito on the Client.

Does Mojito have addons or an API to use a local database?

Mojito does not have any native database solutions, but there is nothing preventing a
developer from using a Node.js modules such as mysql
for a MySQL database or mongodb for a MongoDB
database.