Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Meteor.js: Building Web Applications with Node.js and MongoDB

In this tutorial, we shall learn how to deal with the main topics related to Meteor.js web framework, largely used for the development of web applications, along with Node.js and MongoDB

Prototyping is a practice that allows applications to be structured as code templates or via dial structures (XML, HTML, etc.) thus enabling data to be customized to the detriment of the data source.

Meteor or MeteorJS, is an open-source web framework written in JavaScript Node.js. It was first introduced to the community in December 2011 with the name of Skybreak and was acquired by Meteor Development Group of the Y Combinator startup in 2014 with the objective of expanding the database support (already supplied).

Through it we can rapidly develop prototypes code for applications running on both web browsers and mobile devices (Android, iOS, Windows Phone, etc.). With it, we can also easily integrate the application with MongoDB (Database of NoSQL based on JSON data documents) and use the DDP protocol (Distributed Data Protocol) to propagate changes in data for all real-time service customers without requiring any specific synchronization code.

In this article we will try to clarify the main topics involving this framework by building a quiz application: the user will have access to a registration screen of questions and their options, as well as the list of already created questions will appear in the form below.

The user will also have a pre-established list of questions when accessing the application the first time, since we have not yet populated data.

The information will be stored simultaneously in the database both the client side and the server and any change in either will be printed in the browser, regardless of the client access (Firefox, Chrome, WebView, etc.).

What is the Meteor?

The Meteor concept goes beyond a simple framework; it works as a complete platform that involves technologies such as programming language, database and web services.

Compared with AngularJS, for example, that is a widely used framework to integrate services and business rules in the front end of the application side, Meteor goes further and can handle the same logic on both the client side and the system server. See Figure 1 for a graphical representation of how the framework is divided and the types of tools it supports.

Note that items marked in bold represent technologies that Meteor brings with it already by default, while the others are items also accepted but must be downloaded and installed in the environment.

Figure 1. Division of components and dependencies of Meteor.

Meteor is based on seven principles, namely:

  • Data on the network: Meteor does not send any HTML to the network, instead it sends the data and let the client to render. Thus, we gain in performance for trafficking less information, as we would with Web Services based on Restful and JSON, for example.
  • Only one language: Meteor allows you to write both parties (client and server) of your application in JavaScript. In the client side, this is already standard because of the browser and ECMAScript, the server Node.js comes into play to enable this functionality.
  • Database throughout log: You can also use the same means to access the database on both the client side and the server. This type of strategy differs from what we see in applications that use services to connect with the database, creating unnecessary HTTP requests.
  • Latency compensation: On the client side, the Meteor preloads some data and simulates the data models we have in the server to make the calls to the server look instantaneous. It works similar to the resource cache we have in other frameworks server side as Hibernate c3p0, for example.
  • Automatic layers update: In Meteor real time is the default. All layers from the database to the templates automatically update when necessary. It is like a "hot deploy" for code and layers.
  • Simplicity equals productivity: Meteor has an extremely clean API, with codes and simple methods calls and using all Java code quality standards. As a result, productivity increases by not having to configure everything from scratch in the application.

Furthermore, Meteor also deals with packaging design concepts of binary atmosphere.js via or through Node.js NPM. You can also use the Cordova/PhoneGap packages to perform this work.

No more, for example, set the Gulp for control and automation flows directly in the code, Meteor already has its own built-in feature to keep all dependencies aligned and synchronized.

In addition, to connect with external services and APIs you can make use of the DDP protocol that works as an updating manager: whenever a change occurs in the server, your application will be notified automatically.

Meteor and JavaScript

The main programming language used to develop with the Meteor is JavaScript. But, you can also make use of similar ones like CoffeeScript (which in the end generates JavaScript), jQuery, etc. As Node.js is based on JavaScript if you want to have full support on the server and client sides, it is important to use this language as the default.

Meteor makes use of the names of the directories where the project documents are filed to differentiate between what must be run on the client and the server.

Anything you put in the "\server" will be qualified to run on the server, similarly to the "\client" that will be run on the client. The files in other folders (such as "\lib", for example) will run on both sides.

It is common to find situations where you need to run the same code on both the client and the server, as the definition of data collection and validation of forms that need to have dual layer of security, for example.

However, you are not limited to these two directories; even files that are out of them, can simply use the code shown in Listing 1 to check that it is one or the other. Boolean attributes isClient and isServer help to identify whether we are running on the client or server respectively.

Listing 1. Check the current directory method

if(Meteor.isClient){
    // run client code
  }
  // OR
  if(Meteor.isServer){
    // run server code
  }

Regarding the way we should import the JavaScript files (and CSS) in HTML pages we do not necessarily need to do this within the head tag. Meteor selects them all, minify them and puts them in your application alone. It works similar to what CoffeeScript and Sass make the JS and CSS files, respectively: Meteor has a package manager similar to Ruby gems, for example, packaging all the code with simple commands.

See the following command:

meteor add coffeescript

To enter it on the command line interface you have enabled the screen to enter any commands in CoffeeScript and they will be automatically converted to JavaScript and assimilated to its respective HTML pages.

This is just one of the packages of more than four thousand available that you can find in Meteor specification (see Links section for a complete list of them).

Data Synchronization

Meteor can keep all application data synchronized on both sides of the architecture as well as the structures that hold them. For example, the collections (lists, queues, maps, etc.) in Meteor act as wrappers synchronous data, that is, if you change any data on the server side the same structure that keeps the browser will be updated automatically.

Regarding the templates structures works the same way, Meteor uses the system Spacebars templates for this, which works similar to the famous Handlebars, but with less manipulation of the DOM to keep things faster (very similar to the Facebook API React following the same concept).

Like the JS and CSS files, there’s no need to worry about compiling the templates or sync them manually, Meteor does it all for you.

Meteor makes use of both WebSockets as the DDP protocol to synchronize data. If we make a comparison with the traditional HTTP protocol that most web applications use, we would have something like:

  • This model replaces completely, creating a new internal architecture concept based on asynchronous requests.
  • In the HTTP model the customer does not always know what the server is doing (as it informs the customer when the database is updated) and vice versa. It is a separate relationship, unlike Meteor: everything the customer makes the server knows, and vice versa.

We still have a comparison between the model that makes use of Ajax requests (which are widely used in conjunction with HTTP for increasing the performance of applications) and Meteor. See the amount of requests and the speed with which it moves in the second graph. This is the secret of Meteor: let HTTP (slower) aside and not heavy HTML traffic, only data.

Database

In Meteor, we have two database offices: Mongo and Minimongo. Mongo is located in the server and is a true representation of the data, where in fact the perennial information will be allocated. And Minimongo is a JavaScript library that exists on the client with the intention of simulating a database.

Usually, it only has a subset of Mongo data (unless you decide to publish all the data in an object collection for the client); however, independent of the data you publish Meteor will keep them synchronized: if they change on the client or server.

Environment setup

The installation of Meteor occurs in two ways, depending on your operating system:

1. If you use Linux or any of the operating systems based on OSX, simply run the following statement at the command terminal:

curl https://install.meteor.com/ | sh

2. If you have a Windows then you will need to download the specific installer in Meteor page (see Links section).

The first option will download the file and configure the environment variables automatically. Since most users use Windows, we will show how to set up the same.

After downloading the installer, run it and wait until it downloads all dependencies.

When it finished, a screen as in Figure 2 will appear requesting the login/password of your Meteor account. You can choose to create a new account in the window or log in with an existing one, so your data remains synchronized throughout environment to work. If you do not want, just click on "Skip this step" option.

Figure 2. Login/new account - Meteor.

After this, you need to restart the OS for changes to be saved. Make a quick test to see if everything was successful: open your terminal commands cmd and enter the following command:

meteor –version

You will see the installed version Meteor (the "Meteor 1.x.x.x" format). Now we need to select the directory in which we want to create our Meteor project; navigate to it via terminal and enter the following command:

meteor create quis-mrbool

Three files will also be created for the HTML, JS and CSS project. The latter is empty because no style was also selected for the application getting in charge set. See the code for the first two files in Listings 2 and 3, respectively.

Listing 2. Code for quiz-mrbool.html page.

  01 <head>
  02   <title>quiz-mrbool</title>
  03 </head>
  04 
  05 <body>
  06   <h1>Welcome to Meteor!</h1>
  07 
  08   {{> hello}}
  09 </body>
  10 
  11 <template name="hello">
  12   <button>Click Me</button>
  13   <p>You've pressed the button {{counter}} times.</p>
  14 </template>

Notice that the head tag (line 1 of Listing 2) does not define any JavaScript file import script that we know the project uses. Everything happens by association, Meteor carry alone JS file and analyzes what should be executed on the client. On line 8, we define the "template use" that was created in line 11. The template should always have a name and its contents (button and paragraph) will never appear unless you explain it through the double key operators {{ }} on the page body. This type of selection is common in many JavaScript frameworks such as CoffeeScript, for example.

Listing 3. JavaScript code quiz-mrbool.js file

  01 if (Meteor.isClient) {
  02   // counter starts at 0
  03   Session.setDefault('counter', 0);
  04 
  05   Template.hello.helpers({
  06     counter: function () {
  07       return Session.get('counter');
  08     }
  09   });
  10 
  11   Template.hello.events({
  12     'click button': function () {
  13       // increment the counter when button is clicked
  14       Session.set('counter', Session.get('counter') + 1);
  15     }
  16   });
  17 }
  18 
  19 if (Meteor.isServer) {
  20   Meteor.startup(function () {
  21     // code to run on server at startup
  22   });
  23 }

Regarding JavaScript, realize that the guy we have to check what code belongs to the customer and what the server (isClient/isServer). These values are automatically populated by Meteor to start the server.

In line 3 of Listing 3 add an HTML element to Meteor session scope. The concept is similar to the attributes that have the server side programming languages (such as ASP.NET or Java EE) where each attribute is always made up of the name-value pair. In line 5 we define the helper functions that are utility functions of context. The only function we have is counter() that will return the value of the session variable (the Meteor works with scopes, the session is one of the most comprehensive; we'll talk more about them later). In line 11 we create events, similar to how we map the events in jQuery: through selectors. The string 'click button' says the following function should be performed whenever a click is made on any input type 'button' on the page. The function code, in turn, only increases in a total counter value and saved again in the session. The set() function of Session class always overwrites the value if it already exists, thus preventing that have duplicate values in memory. On line 19 is the code that runs on the server. As no implementation comes standard for this scope, the function is blank.

To run the application does not just simply open the HTML file in a browser, we need to start Node.js server and up the application in it. For this, the command terminal, Step into the project folder (via comand cd) and run the command meteor. After that, the Meteor will rise instances of Node.js, an internal proxy and start the application, showing the end in which address and port you can access (usually http://localhost:3000/). A cursor flashes indicating that the server is up, to stop it just type Ctrl-C.

Go to the address provided on localhost and you'll see the screen shown in Figure 3.

Figure 3. Initial application Meteor screen

Any changes you make in the project files do not need to restart the server, it will automatically deploy the changes and refresh the page alone. Take a test: modify the text of page titles and verify the message "Client modified - refreshing" that appears on the terminal, and the updated page.

Application Construction

Meteor also enables the construction of its application differentiating client code and server via folders. When you create a folder \client and another \server it automatically directs execution to their environments and we no longer have to use the isClient/isServer attributes. Therefore, we will structure our directories as shown in Listing 4.

Listing 4. Structure of project directories

| .meteor
  | client/                       // all client code comes here
      |----- components/          // folder that will contain each component of the project
        |--- quiz-mrbool-form.css
        |--- quiz-mrbool-form.html
        |--- quiz-mrbool-form.js
        |--- quiz-mrbool.css
        |--- quiz-mrbool.html
        |--- quiz-mrbool.js
      |----- app.body.html        // layout for the entire application
      |----- app.head.html       // layout header of the page
      |----- app.js             // js global app
      |----- app.css           // css global app
  | collections/              // will save models of mongo
      |----- quiz.js         // mongo collections
  | server/                 // code to the server
      |----- bootstrap.js // example dates to start the application

The first step to build the application is to create a collection of objects in the mongo. To do this, open the file quiz.js in \collections folder and add the following content to it:

Quiz = new Mongo.Collection('quiz');

That's enough for the collection we need. The reason we created this file in the \collections folder was because we need it in both client and server. Now let's create some sample data for when our application is started. See in Listing 5 content to be added to bootstrap.js file.

Listing 5. Project Boot Code

  01 // this function will be executed when the app is started
  02 Meteor.startup(function() {
  03 
  04   // if it has no quiz available, creates a simple data
  05   if (Quiz.find().count() === 0) {
  06     var quizSimples = [
  07       {
  08         pergunta: 'Do you like Meteor?',
  09         alternativas: [
  10           { texto: 'Yes, very!', votos: 0 },
  11           { texto: 'More or less...', votos: 0 },
  12           { texto: 'No. Prefer JavaScript', votos: 0 }
  13         ]
  14       },
  15       {
  16         pergunta: 'How do you rate this article?',
  17         alternativas: [
  18           { texto: 'bad', votos: 0 },
  19           { texto: 'good', votos: 0 },
  20           { texto: 'excellent', votos: 0 }
  21         ]
  22       }
  23     ];
  24 
  25     // iterates over all quizes and inserts each in the bank
  26     _.each(quizSimple, function(quiz) {
  27       Quiz.insert(quiz);
  28     });
  29   }
  30 });

Note that in line 2 we are using the function of Meteor startup() will be the first to be executed when the project up on the server. In line 5 we see if there is already a given quiz using the method find() MongoDB available through the global object Quiz we have created before. This method lists all the objects added to the bank and the count() method returns the number. If the list come empty created a vector with two filled objects (whose attributes the question and another vector with the alternatives) for testing. The values of the amount of votes that option will be saved as sub-attributes of alternative vector. In line 26 iterate on the quiz items list and insert each in Mongo object by insert() method.

Once the Meteor implements an instance of Mongo on the client, you can run the MongoDB commands directly from the browser console, via developer tool. To have saved all files, Meteor already restarted the application, so the objects that are already created in the database. Open your browser (Chrome will use for the examples shown) and, within the page that execute the Meteor, access the debug console. Type the following command:

Quiz.find().fetch()

The result is the printing of the two objects inserted. Note that there are other attributes that Meteor creates quiz to support the object, such as an identifier (_id) and the vector size (length). This constitutes another benefit of Meteor since the data is always available without the need for debugging using the debugger operator or break points.

Application Template

We need to set our templates that represent the header and body of the page so you do not have to replicate the code in each. Let's start by app.body.html page by adding the contents of Listing 6 to it.

Listing 6. Body of the page template code

  01 <body>
  02   <!-- It's the quiz creation form here -->
  03   <div class="container">
  04     <div class="row">
  05       <div class="col-md-6 col-md-offset-3">
  06         {{ >formQuiz }}
  07       </div>
  08     </div>
  09   </div>  
  10 
  11   <!-- Itera on quizes, displaying them -->
  12   <div class="quiz">
  13       {{ #each quizes }}
  14           {{ >quiz }}
  15       {{ /each }}
  16   </div>
  17 </body>

The page has a simple composition which, in line 6, import the quiz form template, which grafted the HTML inside said div. In this line, the Meteor will look for the file that has the tag <template name = 'formQuiz'>. Note that the classes we are creating are related to Bootstrap: organized in columns.

On line 12 we create a div that will iterate over all quiz items. See the forEach we use on line 13, even repeating structures should be among the double key signals. And once again we import the quiz template on line 14. All import should always start with the highest signal ">", and all end block must end with the name of the command preceded by a slash "/".

We will now edit the header file (Listing 7). This is a common header to other HTML pages. If you check the generated HTML code of the page loaded in the browser will notice that inside the head tag have multiple files being imported (JS and CSS) to keep all logic self-generated by Meteor.

Listing 7. Header template page Code

  01 <head>
  02   <meta charset="utf-8">
  03   <title>My Quiz MrBool!</title>
  04 
  05   <!-- All CSS content will be loaded automatically here -->
  06 </head>

Once with the header and footer templates ready, we can not run them because we must first create the form pages that will use them by default. Open the quiz-MrBool-form.html file and add the contents of Listing 8.

Listing 8. HTML code quiz form page

  01 <template name="formQuiz">
  02     <form> 
  03           <div class="form-group">
  04                  <label>Question</label>
  05                  <input type="text" name="question" class="form-control" placeholder="Your Question">
  06           </div>
  07 
  08           <div class="form-group">
  09                  <label>Opção #1</label>
  10                  <input type="text" name="option1" class="form-control" placeholder="Option #1">
  11           </div>
  12           <div class="form-group">
  13                  <label>Option #2</label>
  14                  <input type="text" name="option2" class="form-control" placeholder="Option #2">
  15           </div>
  16           <div class="form-group">
  17                  <label>Option #3</label>
  18                  <input type="text" name="option3" class="form-control" placeholder="Option #3">
  19           </div>
  20 
  21           <button type="submit" class="btn btn-lg btn-primary btn-block">Create Quiz</button>
  22     </form>
  23 </template>

This time we only HTML content. Note that the tag <template> tag content to be imported; the name must also be the same as those used in importing the body page. Also note that each input field is configured name properties (which will be used to retrieve the field value below), class (with CSS Bootstrap) and placeholder (containing the tip of the field when nothing has been filled).

At the time, the user will be limited to creating only three choices for simplicity, but you can add as you like, including a mechanism to dynamically add more fields. Not to let the compromised view, let's add some CSS to quiz MrBool-form.css file (Listing 9).

Listing 9. CSS code for initial style quiz form page

/* Your CSS goes here */
  .question-group   {
    margin-bottom:20px;
    background:#EEE;
    padding:20px;
  }
  .question-group label   {
    font-size:18px;
  }

Now go back to the page and see the result. Even with the Bootstrap classes added, no style related to it was printed because we still need to import it (we'll do that later). Now create the content of the quiz-mrbool.html page fact. It is there that we will iterate through the list of questions that debugamos and display them. See the code contained in Listing 10.

Listing 10. Code quiz-mrbool.html page

  01 <template name="quiz">
  02     <div class="quiz well well-lg" data-id="{{ _id }}">
  03           
  04           <h3>{{ question }}</h3>
  05 
  06           {{ #each indexedArray alternatives }}
  07                  <a href="#" class="vote btn btn-primary btn-block" data-id="{{ _index }}">
  08                         <span class="votes pull-right">{{ votes }}</span>
  09                         <span class="text">{{ text }}</span>
  10                  </a>
  11           {{ /each }}
  12     </div>
  13 </template>

In line 1 we create a new quiz name template that will be imported in the body page. In line 4 we access the property values in question involving a title h3 tag. After that, in line 6, we iterate over the list of available alternatives printing them in the form of link so that the user can click and vote for the option; and within each link we'll display the current number of votes and the description text. The data-id attribute defined in line 7 with _index value will be responsible for identifying each question with a number suffix.

Now we need to give the body of the page access to the database. To do this we need to assign the variable Mongo the template. See in Listing 11 that code that must be contained in the file app.js.

Listing 11. Code for helper functions in app.js

  01 Template.body.helpers({
  02   quizes: function() {
  03     return Quiz.find();
  04   }
  05 });

This code provides the "quiz" feature to be accessed in the body page. Their only function is to access the database and return the quizes list. Note that also added the indexedArray vector to forEach questions. This was done because we do not have direct access to the indexes when we iterate over lists in Meteor. This is a type of basic resource that Meteor developers are working to include in future versions. Therefore, we need to create this vector within the app.js as in Listing 12.

Listing 12. Code for indexedArray vector iteration

  01 // add an index to each item
  02 UI.registerHelper('indexedArray', function(context, options) {
  03   if (context) {
  04     return context.map(function(item, index) {
  05       item._index = index;
  06       return item;
  07     });
  08   }
  09 });

This code snippet communicates directly with the data-id attribute that we created before: it just creates a kind of record for each index and all the work is done by registerHelper() function inside the Meteor API. Thus, we can now see the options on the screen recharged even without any style.

Form Events

With all the prepared structure, we must now add the events and variables to templates. Each HTML form file has a corresponding JavaScript file. Let's start by quiz-MrBool-form.js (Listing 13).

Listing 13. Event Functions in JS form

  01 Template.formQuiz.events({
  02   // handles the submit form
  03   'submit form': function(event) {
  04 
  05     // prevents the form to send more than once
  06     event.preventDefault();
  07 
  08     // retrieve the form data
  09     var newQuiz = {
  10       pergunta: event.target.question.value,
  11       alternatives: [
  12         {  text: event.target.option1.value, votes: 0 },
  13         {  text: event.target.option2.value, votes: 0 },
  14         {  text: event.target.option3.value, votes: 0 }
  15       ]
  16     };    
  17      
  18     // create the new quiz
  19     Quiz.insert(newQuiz);
  20   }
  21 });

The function events (line 1) should be used whenever you want to add events to a template. In line 3 we are once again regaining the form object via selectors Meteor. In line 6 we prevent the user to perform more than a click on the submit button. In line 9 we create a new instance of questions vector retrieving each of the values entered in the form fields. To retrieve the value of a field by name just access the event object and the target property with the name of the respective field. Already the properties votes start empty.

Finally, in line 19 inserted in the attribute Mongo Quiz object. But we still need to add the vote of events for when the user clicks on the link of each option. Therefore, open the quiz-mrbool.js file and edit it with the contents of Listing 14.

Listing 14. Event functions in the quiz JS

  01 Template.quiz.events({
  02   // event to handle the click on the option
  03   'click .vote': function(event) {
  04 
  05     // prevents double click
  06     event.preventDefault();
  07   
  08     // retrieve the quiz parent id
  09     var idQuiz = $(event.currentTarget).parent('.quiz').data('id');
  10     var idVote = $(event.currentTarget).data('id');
  11 
  12     // create the increment object
  13     var voteString = 'alternatives.' + idVote + '.votes';
  14     var action = {};
  15     action[voteString] = 1;
  16     
  17     // increment the number of votes for this option
  18     Quiz.update(
  19       { _id: idQuiz }, 
  20       { $inc: action }
  21     );
  22   }
  23 });

In line 3 we map the selection to the click event of the CSS class ".voto" on the page. In line 6 we prevent the double click again and on line 9 selected the id of the parent quiz object that will be used to distinguish between the child quiz options. In line 15 we add the initial value of each item quiz while on line 18 to increment in a number of votes for that particular option. The #inc operator will be responsible for it. Now just go to the page and click on the options. You will see the items being updated. If you publish the application and have multiple people using you can see the items updating automatically on every page. Do a test, open your application in two different browsers and spice up the options in a watching them catch up on the other.

Links

Official page of the Meteor installation –

https://www.meteor.com/install

Facebook developers page –

https://developers.facebook.com/

Official MongoDB page –

https://www.mongodb.com/



Fabrí­cio Galdino is a software expert and has worked with IT analysis and business development for more than five years. It has extensive experience with testing, back and front-end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login