- Meteor - Best Practices
- Meteor - ToDo App
- Meteor - Running on mobile
- Meteor - Deployment
- Meteor - Structure
- Meteor - Publish & Subscribe
- Meteor - Package.js
- Meteor - Methods
- Meteor - Accounts
- Meteor - Sorting
- Meteor - Security
- Meteor - Assets
- Meteor - Email
- Meteor - HTTP
- Meteor - EJSON
- Meteor - Timers
- Meteor - Blaze
- Meteor - Check
- Meteor - Core API
- Meteor - Packages
- Meteor - Tracker
- Meteor - Session
- Meteor - Events
- Meteor - Forms
- Meteor - Collections
- Meteor - Templates
- Meteor - First Application
- Meteor - Environment Setup
- Meteor - Overview
- Meteor - Home
Meteor Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Meteor - Quick Guide
Meteor - Overview
According to Meteor official documentation −
Meteor is a full-stack JavaScript platform for developing modern web and mobile apppcations. Meteor includes a key set of technologies for building connected-cpent reactive apppcations, a build tool, and a curated set of packages from the Node.js and general JavaScript community.
Features
Web and Mobile − Meteor offers a platform for developing Web, Android and IOS apps.
Universal Apps − The same code for web browsers and mobile devices.
Packages − Huge number of packages that are easy to install and use.
Meteor Galaxy − Cloud service for Meteor app deployment.
Advantages
Developers only need JavaScript for server and cpent side development.
Coding is very simple and beginner friendly.
Meteor apps are real time by default.
Official and community packages are huge time saver.
Limitations
Meteor isn t very suitable for large and complex apppcations.
There is a lot of magic going on when working with Meteor, so developers might find themselves pmited in some way.
Meteor - Environment Setup
In this chapter, we will learn how to install Meteor on Windows operating system. Before we start working with Meteor, we will need NodeJS. If you don t have it installed, you can check the pnks provided below.
Prerequisite
NodeJS is the platform needed for Meteor development. If you do not have NodeJS environment setup ready, then you can check out our
.Install Meteor
Download the official meteor installer from
If any error occurs during the installation, try running the installer as an administrator. Once the installation is complete, you will be asked to create a Meteor account.
When you finish instalpng Meteor installer, you can test if everything is installed correctly by running the following code in the command prompt window.
C:Usersusername>meteor
Following will be the output −
![Meteor Installation Test](/meteor/images/meteor-installation-test.jpg)
Meteor - First Apppcation
In this chapter, we will learn how to create your first Meteor apppcation.
Step 1 - Create the App
To create the app, we will run the meteor create command from the command prompt window. The apps name will be meteorApp.
C:UsersusernameDesktopMeteor>meteor create meteorApp
Step 2 - Run the App
We can run the app by typing the meteor command.
C:UsersusernameDesktopmeteorApp>meteor
This command will start several processes, which can be seen in the following image.
![Meteor First App Run](/meteor/images/meteor-first-apppcation-run.jpg)
Step 3 - Verify the Result
Now, we can open the http://localhost:3000/ address to see how our first Meteor App looks pke.
![Meteor First App Output](/meteor/images/meteor-first-apppcation-output.jpg)
Meteor - Templates
Meteor templates are using three top level tags. The first two are head and body. These tags perform the same functions as in regular HTML. The third tag is template. This is the place, where we connect HTML to JavaScript.
Simple Template
Following example shows how this works. We are creating a template with name = "myParagraph" attribute. Our template tag is created below the body element, however, we need to include it before it is rendered on the screen. We can do it by using {{> myParagraph}} syntax. In our template, we are using double curly braces ({{text}}). This is meteor template language called Spacebars.
In our JavaScript file, we are setting Template.myParagraph.helpers({}) method that will be our connection to our template. We are only using text helper in this example.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <h1>Header</h1> {{> myParagraph}} </body> <template name = "myParagraph"> <p>{{text}}</p> </template>
meteorApp.js
if (Meteor.isCpent) { // This code only runs on the cpent Template.myParagraph.helpers({ text: This is paragraph... }); }
After we save the changes, following will be the output −
![Meteor Templates Output](/meteor/images/meteor-templates-output.jpg)
Block Template
In the following example, we are using {{#each paragraphs}} to iterate over the paragraphs array and return template name = "paragraph" for each value.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{#each paragraphs}} {{> paragraph}} {{/each}} </span> </body> <template name = "paragraph"> <p>{{text}}</p> </template>
We need to create paragraphs helper. This will be an array with five text values.
meteorApp.js
if (Meteor.isCpent) { // This code only runs on the cpent Template.body.helpers({ paragraphs: [ { text: "This is paragraph 1..." }, { text: "This is paragraph 2..." }, { text: "This is paragraph 3..." }, { text: "This is paragraph 4..." }, { text: "This is paragraph 5..." } ] }); }
Now, we can see five paragraphs on the screen.
![Meteor Templates Output 2](/meteor/images/meteor-templates-output-2.jpg)
Meteor - Collections
In this chapter, we will learn how to use MongoDB collections.
Create a Collection
We can create a new collection with the following code −
meteorApp.js
MyCollection = new Mongo.Collection( myCollection );
Add Data
Once the collection is created, we can add data by using the insert method.
meteorApp.js
MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData);
Find Data
We can use the find method to search for data in the collection.
meteorApp.js
MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); var findCollection = MyCollection.find().fetch(); console.log(findCollection);
The console will show the data we inserted previously.
![Meteor Collection Find](/meteor/images/meteor-collections-find.jpg)
We can get the same result by adding the search parameters.
meteorApp.js
MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); var findCollection = MyCollection.find({key1: "value 1..."}).fetch(); console.log(findCollection);
Update Data
The next step is to update our data. After we have created a collection and inserted new data, we can use the update method.
meteorApp.js
MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); var findCollection = MyCollection.find().fetch(); var myId = findCollection[0]._id; var updatedData = { key1: "updated value 1...", key2: "updated value 2...", key3: "updated value 3...", key4: "updated value 4...", key5: "updated value 5..." } MyCollection.update(myId, updatedData); var findUpdatedCollection = MyCollection.find().fetch(); console.log(findUpdatedCollection);
The console will show that our collection is updated.
![Meteor Collections Update](/meteor/images/meteor-collections-update.jpg)
Delete Data
Data can be deleted from the collection using the remove method. We are setting id in this example as a parameter to delete specific data.
meteorApp.js
MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); var findCollection = MyCollection.find().fetch(); var myId = findCollection[0]._id; MyCollection.remove(myId); var findDeletedCollection = MyCollection.find().fetch(); console.log(findDeletedCollection);
The console will show an empty array.
![Meteor Collections Remove](/meteor/images/meteor-collections-remove.jpg)
If we want to delete everything from the collection, we can use the same method, however, instead of id we will use an empty object {}. We need to do this on the server for security reasons.
meteorApp.js
if (Meteor.isServer) { MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); MyCollection.remove({}); var findDeletedCollection = MyCollection.find().fetch(); console.log(findDeletedCollection); }
We can also delete data using other parameters. As in the previous example, Meteor will force us to do this from the server.
meteorApp.js
if (Meteor.isServer) { MyCollection = new Mongo.Collection( myCollection ); var myData = { key1: "value 1...", key2: "value 2...", key3: "value 3...", key4: "value 4...", key5: "value 5..." } MyCollection.insert(myData); MyCollection.remove({key1: "value 1..."}); var findDeletedCollection = MyCollection.find().fetch(); console.log(findDeletedCollection); }
It can be seen that the data is deleted from the command window.
![Meteor Collections Remove Server](/meteor/images/meteor-collections-remove-server.jpg)
Meteor - Forms
In this chapter, we will learn how to work with Meteor forms.
Text Input
First, we will create a form element with text input field and a submit button.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <form> <input type = "text" name = "myForm"> <input type = "submit" value = "SUBMIT"> </form> </template>
In a JavaScript file, we will create the submit event. We need to prevent default event behavior to stop the browser from refreshing. Next, we are going to take the content of the input field and assign it to textValue variable.
In the following example, we will only log that content to developers console. And the last thing we need is to clear the input field.
meteorApp.js
if (Meteor.isCpent) { Template.myTemplate.events({ submit form : function(event) { event.preventDefault(); var textValue = event.target.myForm.value; console.log(textValue); event.target.myForm.value = ""; } }); }
When we type "Some text..." in our input field and submit it, the console will log the text we entered.
![Meteor Forms Text](/meteor/images/meteor-forms-text.jpg)
Radio Buttons
A similar concept can be used for radio buttons.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <form> <input type = "radio" name = "myForm" value = "form-1">FORM 1 <input type = "radio" name = "myForm" value = "form-2">FORM 2 <input type = "submit" value = "SUBMIT"> </form> </template>
meteorApp.js
if (Meteor.isCpent) { Template.myTemplate.events({ submit form : function(event) { event.preventDefault(); var radioValue = event.target.myForm.value; console.log(radioValue); } }); }
When we submit the first button, the console will show the following output.
![Meteor Forms Radio](/meteor/images/meteor-forms-radio.jpg)
Checkbox
Following example shows how to use checkboxes. You can see that we are just repeating the same process.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <form> <input type = "checkbox" name = "myForm" value = "form-1">FORM 1 <input type = "checkbox" name = "myForm" value = "form-2">FORM 2 <input type = "submit" value = "SUBMIT"> </form> </template>
meteorApp.js
if (Meteor.isCpent) { Template.myTemplate.events({ submit form : function(event) { event.preventDefault(); var checkboxValue1 = event.target.myForm[0].checked; var checkboxValue2 = event.target.myForm[1].checked; console.log(checkboxValue1); console.log(checkboxValue2); } }); }
Once the form is submitted, the checked input will be logged as true, while the unchecked one will be logged as false.
![Meteor Forms Checkbox](/meteor/images/meteor-forms-checkbox.jpg)
Select Dropdown
In the following example, we will learn how to use the select element. We will use the change event to update data every time the option changes.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <select> <option name = "myOption" value = "option-1">OPTION 1</option> <option name = "myOption" value = "option-2">OPTION 2</option> <option name = "myOption" value = "option-3">OPTION 3</option> <option name = "myOption" value = "option-4">OPTION 4</option> </select> </template>
meteorApp.js
if (Meteor.isCpent) { Template.myTemplate.events({ change select : function(event) { event.preventDefault(); var selectValue = event.target.value; console.log(selectValue); } }); }
If we choose the third option, the console will log the option value.
![Meteor Forms Select](/meteor/images/meteor-forms-select.jpg)
Meteor - Events
In this chapter, we will learn how to use tag, class and id as an event selector. Working with events is pretty straightforward.
Let s create three elements in the HTML template. The first one is p, the second one is myClass class and the last one is myId id.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <p>PARAGRAPH...</p> <button class = "myClass">CLASS</button> <button id = "myId">ID</button> </template>
In our JavaScript file, we are setting three events for three elements that we created above. You can see that we are just adding p, .myClass and #myId after the cpck event. These are the selectors we mentioned above.
meteorApp.js
if (Meteor.isCpent) { Template.myTemplate.events({ cpck p : function() { console.log("The PARAGRAPH is cpcked..."); }, cpck .myClass : function() { console.log("The CLASS is cpcked..."); }, cpck #myId : function() { console.log("The ID is cpcked..."); }, }); }
To test this, we can first cpck on PARAGRAPH, then the CLASS button and finally the ID button. We will get the following console log.
![Meteor Events Log](/meteor/images/meteor-events-example.jpg)
We can use all the other JavaScript events - cpck, dbcpck, contextmenu, mousedown, mouseup, mouseover, mouseout, mousemove - following the example above.
Meteor - Session
Sessions are used for saving data while the users are using the app. This data will be deleted when the user leaves the app.
In this chapter, we will learn how to set a session object, store some data, and return that data. We will use the basic HTML setup.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> </template>
Now, we will store myData locally using Session.set() method. Once the method is set, we can return it using Session.get() method.
meteorApp.js
if (Meteor.isCpent) { var myData = { key1: "value1", key2: "value2" } Session.set( mySession , myData); var sessionDataToLog = Session.get( mySession ); console.log(sessionDataToLog); }
If we check the console, we will see that the stored data is logged.
![Meteor Session Log](/meteor/images/meteor-session-log.jpg)
In the next chapter, we will learn how to auto-update templates using the Session variable.
Meteor - Tracker
Tracker is a small pbrary used for auto updating templates once the Session variable has changed. In this chapter, we will learn how the tracker works.
First, we will create a button that will be used for updating the session.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <button id = "myButton">CLICK ME</button> </template>
Next, we will set the starting session value myData and create a mySession object. Tracker.autorun method is used for keeping an eye on mySession. Whenever this object changes, the template will auto-update. To test it, we will set a cpck event for updating.
meteorApp.js
if (Meteor.isCpent) { var myData = 0 Session.set( mySession , myData); Tracker.autorun(function () { var sessionData = Session.get( mySession ); console.log(sessionData) }); Template.myTemplate.events({ cpck #myButton : function() { Session.set( mySession , myData ++); } }); }
If we cpck the CLICK ME button five times, we will see that the tracker is logging new values every time the session updates.
![Meteor Tracker Log](/meteor/images/meteor-tracker-log.jpg)
Meteor - Packages
Meteor offers thousands of community packages that you can use while developing your app.
Adding Packages
You can check the official Meteor package server
. Just search for the package you need and add it in the command prompt window. If, for example, you want to add http package to your app, you can do it by running the following code −C:UsersusernameDesktopmeteorApp>meteor add http
Removing Packages
A similar principle can be used to remove packages −
C:UsersusernameDesktopmeteorApp>meteor remove http
Updating Packages
You can update the package running the following code −
C:UsersusernameDesktopmeteorApp>meteor update http
Checking Current Packages
You can also check what packages your current apppcation is using.
C:UsersusernameDesktopmeteorApp>meteor pst
Package Maintenance
If a package has : in the name, it means that it is a community package, while the ones without the prefix are maintained by the Meteor Development group.
Adding Meteor Development Group Package
C:UsersusernameDesktopmeteorApp>meteor add http
Adding Community Package
C:UsersusernameDesktopmeteorApp>meteor add cfs:http-methods
Meteor - Core Api
If you want to pmit the code to run only on the server or the cpent side, you can use the following code −
meteorApp.js
if (Meteor.isCpent) { // Code running on cpent... } if (Meteor.isServer) { // Code running on server... }
You can pmit the code to run only when the app is using Cordova bundpng.
if (Meteor.isCordova) { // Code running on Cordova... }
Some plugins need to wait until the server and DOM are ready. You can use the following code to wait until everything begins.
Meteor.startup(function () { // Code running after platform is ready... });
Following table psts some other core API methods.
Sr.No. | Method & Details |
---|---|
1 | Meteor.wrapAsync(function) Used for wrapping asynchronous code and convert it into synchronous. |
2 | Meteor.absoluteUrl([path], [options]) Used for generating absolute URL pointing to the app. |
3 | Meteor.settings Used for setting deployment configuration. |
4 | Meteor.pubpsh(name, function) Used for pubpshing records to the cpent. |
Meteor - Check
The check method is used for find out if the argument or types are matching the pattern.
Instalpng Check Package
Open the command prompt window and install the package.
C:UsersusernameDesktopmeteorApp>meteor add check
Using Check
In the following example, we want to check if myValue is a string. Since it is true, the app will proceed without any errors.
meteorApp.js
var myValue = My Value... ; check(myValue, String);
In this example, myValue is not a string but a number, hence the console will log an error.
meteorApp.js
var myValue = 1; check(myValue, String);
![Meteor Check Log Error](/meteor/images/meteor-check-log-error.jpg)
Match Test
The Match.test is similar to check, the difference being when the test fails instead of a console error, we will get a value without breaking the server. The following example shows how to test an object with multiple keys.
meteorApp.js
var myObject = { key1 : "Value 1...", key2 : "Value 2..." } var myTest = Match.test(myObject, { key1: String, key2: String }); if ( myTest ) { console.log("Test is TRUE..."); } else { console.log("Test is FALSE..."); }
Since the both keys are strings, the test is true. The console will log the first option.
![Meteor Match Test True](/meteor/images/meteor-match-test-true.jpg)
If we change the key2 to number, the test will fail and the console will log the second option.
meteorApp.js
var myObject = { key1 : "Value 1...", key2 : 1 } var myValue = 1; var myTest = Match.test(myObject, { key1: String, key2: String }); if ( myTest ) { console.log("Test is TRUE..."); } else { console.log("Test is FALSE..."); }
![Meteor Match Test False](/meteor/images/meteor-match-test-false.jpg)
Meteor - Blaze
Blaze is a Meteor package for building pve reactive templates.
Render Method
This method is used for rendering templates into the DOM. First, we will create myNewTemplate that will be rendered. We will also add myContainer, which will be used as a parent element, so the render method knows where to render our template.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span id = "myContainer"> </span> </body> <template name = "myNewTemplate"> <p>Text from my new template...</p> </template>
Next, we will create a render function that will take two arguments. The first one is a template that will be rendered and the second one is a parent element that we mentioned above.
meteorApp.js
Meteor.startup(function () { if(Meteor.isCpent) { var myNewTemplate = Template.myNewTemplate; var myContainer = document.getElementById( myContainer ); Blaze.render(myNewTemplate, myContainer); } });
![Meteor Blaze Render](/meteor/images/meteor-blaze-render.jpg)
Render with Data
If you need to pass some data reactively, you can use renderWithData method. The HTML will be exactly the same as in the previous example.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span id = "myContainer"> </span> </body> <template name = "myNewTemplate"> <p>Text from my new template...</p> </template>
We can add our data as a second argument in Meteor.renderWithData method. The other two arguments are the same as in the previous example. In this example, our data is a function that will log some text.
meteorApp.js
Meteor.startup(function () { if(Meteor.isCpent) { var myNewTemplate = Template.myNewTemplate; var myData = function() { console.log( Log from the data object... ) } var myContainer = document.getElementById( myContainer ); Blaze.renderWithData(myNewTemplate, myData, myContainer); } });
![Meteor Blaze Render With Data](/meteor/images/meteor-blaze-render-with-data.jpg)
Remove Method
We can add remove method.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span id = "myContainer"> </span> </body> <template name = "myNewTemplate"> <p>Text from my new template...</p> </template>
In this example, we are rendering the template that will be removed after three seconds. Notice the Blaze.Remove method that we are using to remove the template.
meteorApp.js
Meteor.startup(function () { if(Meteor.isCpent) { var myNewTemplate = Template.myNewTemplate; var myContainer = document.getElementById( myContainer ); var myRenderedTemplate = Blaze.render(myNewTemplate, myContainer); Meteor.setTimeout(function() { Blaze.remove(myRenderedTemplate); }, 3000); } });
The following table shows the other methods that can be used.
Sr.No. | Method & Details |
---|---|
1 | Blaze.getData([elementOrView]) Used for retrieving data from the rendering element. |
2 | Blaze.toHTML(templateOrView) Used for rendering templates or views to the string. |
3 | Blaze.toHTMLWithData(templateOrView, data) Used for rendering templates or views to the string with additional data. |
4 | new Blaze.View([name], renderFunction) Used for creating a new Blaze reactive part of the DOM. |
5 | Blaze.currentView Used for getting the current view. |
6 | Blaze.getView([element]) Used for getting the current view. |
7 | Blaze.With(data, contentFunc) Used for constructing a view that renders some content with context. |
8 | Blaze.If(conditionFunc, contentFunc, [elseFunc]) Used for constructing a view that renders some conditional content. |
9 | Blaze.Unless(conditionFunc, contentFunc, [elseFunc]) Used for constructing a view that renders some conditional content (inverted Blaze.if). |
10 | Blaze.Each(argFunc, contentFunc, [elseFunc]) Used for constructing a view that renders contentFunct for every item. |
11 | new Blaze.Template([viewName], renderFunction) Used for constructing a new Blaze view with name and content. |
12 | Blaze.isTemplate(value) Used for returning true, if the value is a template object. |
Meteor - Timers
Meteor offers its own setTimeout and setInterval methods. These methods are used to make sure that all global variables have correct values. They work pke regular JavaScript setTimout and setInterval.
Timeout
This is Meteor.setTimeout example.
Meteor.setTimeout(function() { console.log("Timeout called after three seconds..."); }, 3000);
We can see in the console that the timeout function is called once the app has started.
![Meteor Timeout](/meteor/images/meteor-timeout.jpg)
Interval
Following example shows how to set and clear an interval.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> <span> {{> myTemplate}} </span> </body> <template name = "myTemplate"> <button>CLEAR</button> </template>
We will set the initial counter variable that will be updated after every interval call.
meteorApp.js
if (Meteor.isCpent) { var counter = 0; var myInterval = Meteor.setInterval(function() { counter ++ console.log("Interval called " + counter + " times..."); }, 3000); Template.myTemplate.events({ cpck button : function() { Meteor.clearInterval(myInterval); console.log( Interval cleared... ) } }); }
The console will log the updated counter variable every three seconds. We can stop this by cpcking the CLEAR button. This will call the clearInterval method.
![Meteor Interval](/meteor/images/meteor-interval.jpg)
Meteor - EJSON
EJSON is an extension of JSON syntax that supports Date and Binary types.
Install EJSON
To install EJSON package, we need to add it from the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor add ejson
Date Example
We can deseriapze the date using the parse method.
if (Meteor.isCpent) { var myEjsonDate = {"$date": 1455029631493} ; var myDate = EJSON.parse(myEjsonDate); console.log(myDate); }
The console will log the correct date value.
![Meteor EJSON Date](/meteor/images/meteor-ejson-date.jpg)
Binary Example
The same can be appped to binary types.
if (Meteor.isCpent) { var myEjsonBinary = {"$binary": "c3VyZS4="} ; var myBinary = EJSON.parse(myEjsonBinary); console.log(myBinary); }
You can see that the console is logging new deseriapzed value.
![Meteor EJSON Binary](/meteor/images/meteor-ejson-binary.jpg)
Stringify
We can seriapze an object using the stringify method. This is the reversed process from the example above.
if (Meteor.isCpent) { var myObject = { myDate : new Date(), myBinary : new Uint8Array([115, 117, 114, 101, 46]) } var myEjosnData = EJSON.stringify(myObject); console.log(myEjosnData); }
We can see our new values in the console.
![Meteor EJSON Stringify](/meteor/images/meteor-ejson-stringify.jpg)
Sr.No. | Method & Details |
---|---|
1 | EJSON.parse(string) Used for parsing a string into EJSON value. |
2 | EJSON.stringify(value) Used for seriapzing a value to the string. |
3 | EJSON.fromJSONValue(value) Used for deseriapzing an EJSON value from JSON. |
4 | EJSON.toJSONValue(value) Used for seriapzing an EJSON value into JSON. |
5 | EJSON.equals(value1, value2) Used for comparing if two values are equal. |
6 | EJSON.clone(value) Used for returning a deep copy of the value. |
7 | EJSON.newBinary Used for assigning a binary data that EJSON can seriapze. |
8 | EJSON.isBinary(x) Used for checking if the value is a binary data. |
9 | EJSON.addType(name, factory) Used for creating a custom EJSON type. |
10 | customType.typeName() Used for returning a name of the custom type. |
11 | customType.toJSONValue() Used for seriapzing custom types. |
12 | customType.clone() Used for returning a deep copy of the custom type. |
13 | customType.equals(otherValue) Used for comparison between the custom type value and other value. |
Meteor - HTTP
This package provides HTTP request API with get, post, put and delete methods.
Install Package
We will install this package by running the following code in the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor add http
CALL Method
This is universal method that can use GET, POST, PUT and DELETE arguments. The following example demonstrates how to use GET argument. The examples in this chapter will use fake REST API from
.You can see that this method is using four arguments. We already mentioned the first argument GET. The second one is API URL. The third argument is an empty object, where we can set some optional parameters. The last method is an asynchronous callback, where we can handle errors and work with a response.
HTTP.call( GET , http://jsonplaceholder.typicode.com/posts/1 , {}, function( error, response ) { if (error) { console.log(error); } else { console.log(response); } });
GET Method
The same request can be sent using GET instead of CALL method. You can see that the first argument now is API URL.
HTTP.get( http://jsonplaceholder.typicode.com/posts/1 , {}, function( error, response ) { if ( error ) { console.log( error ); } else { console.log( response ); } });
Both of the previous examples will log the same output.
![Meteor HTTP Call](/meteor/images/meteor-http-call.jpg)
POST Method
In this method, we are setting data that needs to be sent to the server (postData) as the second argument. Everything else is the same as in our GET request.
var postData = { data: { "name1": "Value1", "name2": "Value2", } } HTTP.post( http://jsonplaceholder.typicode.com/posts , postData, function( error, response ) { if ( error ) { console.log( error ); } else { console.log( response); } });
The console will log our postData object.
![Meteor HTTP Post](/meteor/images/meteor-http-post.jpg)
PUT Method
We can update our data using the PUT method. The concept is the same as in our last example.
var updateData = { data: { "updatedName1": "updatedValue1", "UpdatedName2": "updatedValue2", } } HTTP.put( http://jsonplaceholder.typicode.com/posts/1 , updateData, function( error, response ) { if ( error ) { console.log( error ); } else { console.log( response ); } });
Now, we can see our updated object in the console.
![Meteor HTTP Put](/meteor/images/meteor-http-put.jpg)
DEL Method
We can send a delete request to the server using the DEL method. We will delete everything inside the data object.
var deleteData = { data: {} } HTTP.del( http://jsonplaceholder.typicode.com/posts/1 , deleteData, function( error, response ) { if ( error ) { console.log( error ); } else { console.log( response ); } });
The console will show that the deleting process is successful.
![Meteor HTTP Del](/meteor/images/meteor-http-del.jpg)
Meteor - Email
This package is used when you need to send an email from Meteor App.
Step 1 - Add Package
Open the command prompt window and run the following command −
C:UsersusernameDesktopmeteorApp>meteor add email
Step 2 - Mailgun Account
We need to create an account
. This is the default email provider for Meteor apps.After you are logged in, open the Domains tab and cpck the sandbox URL below the Domain Name. It will open a new page where we can find Default SMTP Login and Default Password. We will need these two for creating the MAIL_URL environment variable.
Send Email
To create a vapd MAIL_URL just insert your Mailgun credentials in place of YOUR_DEFAULT_SMTP_LOGIN and YOUR_DEFAULT_PASSWORD.
if (Meteor.isServer) { Meteor.startup( function() { process.env.MAIL_URL = "smtp://YOUR_DEFAULT_SMTP_LOGIN:YOUR_DEFAULT_PASSWORD@smtp.mailgun.org:587"; Email.send({ to: "toemailadress@email.com", from: "fromemailadress@email.com", subject: "Meteor Email", text: "The email content..." }); }); }
When you run the app, the email will be sent to your address.
![Meteor Email Received](/meteor/images/meteor-email-received.jpg)
Meteor - Assets
Static server assets are located in a private subfolder inside the app. In the following example, we will learn how to use data from a simple JSON file.
Step 1 - Create Files and Folders
Let s create a private folder and my-json.json file inside that folder. We will do this using the following command in the command prompt window, however, you can also create it manually.
C:UsersusernameDesktopmeteorApp>mkdir private C:UsersusernameDesktopmeteorAppprivate>touch my-json.json
Step 2 - Get Text
To be able to read data from our file, we will use Asssets.getText method. Note, this can only be done from the server side. Since we are using JSON, we need to parse it.
if (Meteor.isServer) { var myFile = JSON.parse(Assets.getText( my-json.json )); console.log(myFile.data.text) }
Following will be the output in the command prompt window.
![Meteor Assets Get Text](/meteor/images/meteor-assets-get-text.jpg)
Step 3 - Create EJSON File
We will create this file inside the private folder. This file will contain binary data "myBinary": {"$binary": "c3VyZS4="}
C:UsersusernameDesktopmeteorAppprivate>touch my-ejson.ejson
Step 4 - Get Binary
To read EJSON files, we can use the Assets.getBinary method.
if (Meteor.isServer) { var myFile = Assets.getBinary( my-ejson.ejson ); console.log(EJSON.stringify(myFile)); }
The command prompt will log EJSON value.
![Meteor Assets Get Binary](/meteor/images/meteor-assets-get-binary.jpg)
Meteor - Security
In this chapter, we will learn how to secure our app and what should be taken into consideration while developing an app.
Autopubpsh and Autosecure
Autopubpsh is a package that automatically pubpshes all data from the database to the cpent. This is a convenience that should be disabled when in production. It can be disabled from the command prompt.
C:UsersusernameDesktopmeteorApp>meteor remove autopubpsh
You can pubpsh some data to the cpent by using Meteor.pubpsh() and Meteor.subscribe() methods that we will cover in the Pubpsh and Subscribe chapter.
Insecure is a package that allows MongoDB commands to be written in developer’s console, so that every user of the app is able to access the database. The package can be removed by running the following command in the command prompt.
C:UsersusernameDesktopmeteorApp>meteor remove insecure
Good practice is to remove both of the packages as soon as you start developing your app, so you don t have to change and update your code later.
Use Server Side Methods
You should always create your methods on the server. You can do it by using the Meteor.methods() on the server and Meteor.call() on the cpent. We will learn more about this in the Methods chapter.
Additional Security
If you want to add additional layers of security to your app, you should consider using some other Meteor packages such as −
can be used to control the external resources that should be loaded to your app.
package can be used to check the user input types before they are processed.
is a package that will ensure all parameters are correctly checked before processed. If you missed some parameters, this package will inform you.
packages can add some additional layers of security. You can check them out if you need that kind of protection.
Meteor - Sorting
We can sort the data once we get it from the database. In the following example, we will create Users collection. We will use a sort argument ({sort: {name: 1}}) for sorting the collection data by name. The number 1 is used to set the ascending order. If we want to use the descending order, we would use -1 instead.
Users = new Mongo.Collection( users ); Users.insert({ name: James , email: eee@example.com , joined: new Date(2016, 2, 23) }); Users.insert({ name: John , email: iii@example.com , joined: new Date(2016, 2, 19) }); Users.insert({ name: Jennifer , email: aaa@example.com , joined: new Date(2016, 6, 24) }); var sortByName = Users.find({}, {sort: {name: 1}}).fetch(); var sortByEmail = Users.find({}, {sort: {email: 1}}).fetch(); var sortByJoined = Users.find({}, {sort: {joined: 1}}).fetch(); console.log(sortByName); console.log(sortByEmail); console.log(sortByJoined);
![Meteor Sorting Name](/meteor/images/meteor-sorting-name.jpg)
We can sort the data by email the same way.
Users = new Mongo.Collection( users ); Users.insert({ name: James , email: eee@example.com , joined: new Date(2016, 2, 23) }); Users.insert({ name: John , email: iii@example.com , joined: new Date(2016, 2, 19) }); Users.insert({ name: Jennifer , email: aaa@example.com , joined: new Date(2016, 6, 24) }); var sortByEmail = Users.find({}, {sort: {email: 1}}).fetch(); console.log(sortByEmail);
![Meteor Sorting Email](/meteor/images/meteor-sorting-email.jpg)
Finally, we can sort it by the joining date.
Users = new Mongo.Collection( users ); Users.insert({ name: James , email: eee@example.com , joined: new Date(2016, 2, 23) }); Users.insert({ name: John , email: iii@example.com , joined: new Date(2016, 2, 19) }); Users.insert({ name: Jennifer , email: aaa@example.com , joined: new Date(2016, 6, 24) }); var sortByJoined = Users.find({}, {sort: {joined: 1}}).fetch(); console.log(sortByJoined);
![Meteor Sorting Joined](/meteor/images/meteor-sorting-joined.jpg)
Meteor - Accounts
This package allows complete user authentication functionapty. You can add it by running the following code in the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor add accounts-password
Authentication Example
This example will show basic authentication. We will create register, login, and home templates. If there is a currentUser (if the user is successfully registered or logged in), the home template will be shown. If there is no currentUser, the register and login templates will be visible.
meteorApp.html
<head> <title>meteorApp</title> </head> <body> {{#if currentUser}} {{> home}} {{else}} {{> register}} {{> login}} {{/if}} </body> <template name = "register"> <h2>REGISTER:</h2> <form> <input type = "email" name = "registerEmail"><br> <input type = "password" name = "registerPassword"><br> <input type = "submit" value = "Register"><br> </form> </template> <template name = "login"> <h2>LOGIN:</h2> <form> <input type = "email" name = "loginEmail"><br> <input type = "password" name="loginPassword"><br> <input type = "submit" value = "Login"><br> </form> </template> <template name = "home"> <p>You re logged in.</p> <button class = "logout">Logout</button> </template>
First, we need to create a register event. This function will read register inputs, create a new user, and store it to the database.
The second event is login. This time the function will read inputs from the login template, log in the user if the email and password are vapd or return an error if they aren t.
And finally the logout event will be used for logging out the user, once the button is cpcked.
meteorApp.js
if (Meteor.isCpent) { Template.register.events({ submit form : function(event) { event.preventDefault(); var registerData = { email: event.target.registerEmail.value, password: event.target.registerPassword.value } Accounts.createUser(registerData, function(error) { if (Meteor.user()) { console.log(Meteor.userId()); } else { console.log("ERROR: " + error.reason); } }); } }); Template.login.events({ submit form : function(event) { event.preventDefault(); var myEmail = event.target.loginEmail.value; var myPassword = event.target.loginPassword.value; Meteor.loginWithPassword(myEmail, myPassword, function(error) { if (Meteor.user()) { console.log(Meteor.userId()); } else { console.log("ERROR: " + error.reason); } }); } }); Template.home.events({ cpck .logout : function(event) { event.preventDefault(); Meteor.logout(function(error) { if(error) { console.log("ERROR: " + error.reason); } }); } }); }
Once the app starts, we will get the following page.
![Meteor Accounts Start](/meteor/images/meteor-accounts-start.jpg)
On entering the email and password in the register form, we can register and login the new user. We will see that the console logs the users id and the home template is rendered.
![Meteor Accounts Register](/meteor/images/meteor-accounts-register.jpg)
The login event will check the database and log in the user, if the email and password are correct. If not, the console will log an error.
![Meteor Accounts Login Error](/meteor/images/meteor-accounts-login-error.jpg)
If the user cpcks the LOGOUT button, the app will log the user out and show the register and login templates.
Meteor - Methods
Meteor methods are functions that are written on the server side, but can be called from the cpent side.
On the server side, we will create two simple methods. The first one will add 5 to our argument, while the second one will add 10.
Using Methods
meteorApp.js
if(Meteor.isServer) { Meteor.methods({ method1: function (arg) { var result = arg + 5; return result; }, method2: function (arg) { var result = arg + 10; return result; } }); } if(Meteor.isCpent) { var aaa = aaa Meteor.call( method1 , aaa, function (error, result) { if (error) { console.log(error); else { console.log( Method 1 result is: + result); } } ); Meteor.call( method2 , 5, function (error, result) { if (error) { console.log(error); } else { console.log( Method 2 result is: + result); } }); }
Once we start the app, we will see the calculated values in console.
![Meteor Methods Log](/meteor/images/meteor-methods-log.jpg)
Handpng Errors
For handpng errors, you can use the Meteor.Error method. The following example shows how to handle error for users that aren t logged in.
if(Meteor.isServer) { Meteor.methods({ method1: function (param) { if (! this.userId) { throw new Meteor.Error("logged-out", "The user must be logged in to post a comment."); } return result; } }); } if(Meteor.isCpent) { Meteor.call( method1 , 1, function (error, result) { if (error && error.error === "logged-out") { console.log("errorMessage:", "Please log in to post a comment."); } else { console.log( Method 1 result is: + result); }}); }
The console will show our customized error message.
![Meteor Methods Error](/meteor/images/meteor-methods-error.jpg)
Meteor - Package.js
In this chapter, we will learn how to create our own meteor package.
Creating a Package
Let s add a new folder on the desktop, where the package will be created. We will use the command prompt window.
C:UsersusernameDesktopmeteorApp> mkdir packages
Now, we can create the package in the folder we have created above. Run the following command from the command prompt. Username is the Meteor Developer username and package-name is the name of the package.
C:UsersusernameDesktopmeteorApppackages>meteor create --package username:package-name
Adding a Package
To be able to add a local package to our app, we need to set the ENVIRONMENT VARIABLE that will tell Meteor to load the package from the local folder. Right-cpck the computer icon and choose properties/Advanced system settings/Environment Variables/NEW.
Variable Name should be PACKAGE_DIRS. Variable Value should be the path to the folder we created. In our case, C:UsersusernameDesktopmeteorApppackages.
Don t forget to restart the command prompt after adding a new Environment Variable.
We can now add the package to our app by running the following code −
C:UsersusernameDesktopmeteorApp>meteor add username:package-name
Package Files
Following four files will be found in the package we created.
package-name-test.js
package-name.js
package.js
README.md
Testing Package (package-name-test.js)
Meteor offers tinytest package for testing. Let s install it first using the following command in the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor add tinytest
If we open package-name-test.js, we will see the default test example. We will use this example to test the app. Note: It is always better to write our own tests when developing meteor packages.
To test the package, let us run this code in the command prompt.
C:UsersusernameDesktop>meteor test-packages packages/package-name
We will get the following result.
![Meteor Package Test](/meteor/images/meteor-package-js-test.jpg)
package.js File
This is the file where we can write the code. Let s create some simple functionapty for our package. Our package will log some text in the console.
packages/package.js
myPackageFunction = function() { console.log( This is simple package... ); }
package-name.js File
This is the file where we can set some package configuration. We will get back to it later, but for now we need to export myPackageFunction so we can use it in our app. We need to add this inside Package.onUse function. The file will look something pke this.
packages/package-name.js
Package.describe({ name: username:package-name , version: 0.0.1 , // Brief, one-pne summary of the package. summary: , // URL to the Git repository containing the source code for this package. git: , // By default, Meteor will default to using README.md for documentation. // To avoid submitting documentation, set this field to null. documentation: README.md }); Package.onUse(function(api) { api.versionsFrom( 1.2.1 ); api.use( ecmascript ); api.addFiles( mypackage.js ); api.export( myPackageFunction ); // We are exporting the function we created above... }); Package.onTest(function(api) { api.use( ecmascript ); api.use( tinytest ); api.use( username:package-name ); api.addFiles( package-name-tests.js ); });
Using a Package
Now we can finally call the myPackageFunction() from our meteorApp.js file.
packages/package.js
if(Meteor.isCpent) { myPackageFunction(); }
The console will log the text from our package.
![Meteor Package Log](/meteor/images/meteor-package-js-log.jpg)
To better understand how the package.js file can be configured, we will use the example from Meteor official documentation.
This is an example file...
/* Information about this package */ Package.describe({ // Short two-sentence summary. summary: "What this does", // Version number. version: "1.0.0", // Optional. Default is package directory name. name: "username:package-name", // Optional github URL to your source repository. git: "https://github.com/something/something.git", }); /* This defines your actual package */ Package.onUse(function (api) { // If no version is specified for an api.use dependency, use the // one defined in Meteor 0.9.0. api.versionsFrom( 0.9.0 ); // Use Underscore package, but only on the server. // Version not specified, so it will be as of Meteor 0.9.0. api.use( underscore , server ); // Use iron:router package, version 1.0.0 or newer. api.use( iron:router@1.0.0 ); // Give users of this package access to the Templating package. api.imply( templating ) // Export the object Email to packages or apps that use this package. api.export( Email , server ); // Specify the source code for the package. api.addFiles( email.js , server ); }); /* This defines the tests for the package */ Package.onTest(function (api) { // Sets up a dependency on this package api.use( username:package-name ); // Allows you to use the tinytest framework api.use( tinytest@1.0.0 ); // Specify the source code for the package tests api.addFiles( email_tests.js , server ); }); /* This lets you use npm packages in your package*/ Npm.depends({ simplesmtp: "0.3.10", "stream-buffers": "0.2.5" });
Meteor - Pubpsh and Subscribe
As already discussed in the Collections chapter, all of our data is available on the cpent side. This is a security issue that can be handled with pubpsh and subscribe methods.
Removing Autopubpsh
In this example, we will use PlayersCollection collection with the following data. We prepared this collection before to be able to concentrate on the chapter itself. If you are unsure how to create MongoDB collections in meteor app, check our
chapter.![Meteor Pubpsh and Subscribe Database Data](/meteor/images/meteor-pubpsh-and-subscribe-database-data.jpg)
To secure our data, we need to remove autopubpsh package that was allowing us to use the data on the cpent side.
C:UsersusernameDesktopmeteorApp>meteor remove autopubpsh
After this step, we will not be able to get the database data from the cpent side. We will only be able to see it from the server side in the command prompt window. Checkout the following code −
meteorApp.js
var PlayersCollection = new Mongo.Collection( playersCollection ); var myLog = PlayersCollection.find().fetch(); console.log(myLog);
The command prompt window will show the entire collection with four objects, while the developers console will show an empty array. Now our app is more secure.
![Meteor Pubpsh and Subscribe Autopubpsh Removed](/meteor/images/meteor-pubpsh-and-subscribe-autopubpsh-removed.jpg)
Using Pubpsh and Subscribe
Let s say we want to allow the cpents to use our data. For this, we need to create Meteor.pubpsh() method on the server. This method will send the data to the cpent.
To be able to receive and use that data on the cpent side, we will create Meteor.subscribe() method. At the end of the example, we are searching the database. This code is running on both the cpent and the server side.
var PlayersCollection = new Mongo.Collection( playersCollection ); if(Meteor.isServer) { Meteor.pubpsh( allowedData , function() { return PlayersCollection.find(); }) } if (Meteor.isCpent) { Meteor.subscribe( allowedData ); }; Meteor.setTimeout(function() { var myLog = PlayersCollection.find().fetch(); console.log(myLog); }, 1000);
We can see that our data is logged in both the developers console and the command prompt window.
![Meteor Pubpsh and Subscribe Allowed All](/meteor/images/meteor-pubpsh-and-subscribe-allowed-all.jpg)
Filtering Cpent Data
We can also pubpsh part of the data. In this example, we are pubpshing data with name = "John".
var PlayersCollection = new Mongo.Collection( playersCollection ); if(Meteor.isServer) { Meteor.pubpsh( allowedData , function() { return PlayersCollection.find({name: "John"}); }) } if (Meteor.isCpent) { Meteor.subscribe( allowedData ); }; Meteor.setTimeout(function() { myLog = PlayersCollection.find().fetch(); console.log(myLog); }, 1000);
Once we run this code, the command prompt will log all of the data, while the cpent side console will just log two objects with the name John.
![Meteor Pubpsh and Subscribe Allowed All](/meteor/images/meteor-pubpsh-and-subscribe-allowed-john.jpg)
Meteor - Structure
Meteor offers some special folders that can help the developers’ in structuring their apps.
cpent
If you create a cpent folder, everything inside this folder will be run on the cpent side. This is the folder where you can place your HTML, CSS, and cpent side JavaScript. You should place Meteor.subscribe functions, templates, helpers, and events inside this folder. Note, you don t need to run the Meteor.isCpent function in the files that are placed inside the cpent folder.
server
Files from this folder will only be run on the server side. This is the place where methods, Meteor.Pubpsh() functions, and other sensitive data should be held. All of the authentication data should be held here. You don t need to use Meteor.isServer() for the files inside this folder.
pubpc
This is the place where you should place your images, favicons, and all the other data that is served to the cpent.
private
Files from this folder can be accessed only from the server. They will be hidden from the cpent. You can put JSON or EJSON files that only the server will use inside this folder.
cpent/compatibipty
Some JavaScript pbraries export variables as globals. Use this folder for files that need to be executed without being wrapped in a new variable scope.
The rest
The rest of the folders can be structured the way you want. The code that is placed outside of the folders mentioned above will be executed on the cpent and the server side. This is a good place where you can define your models.
Load Order
It is always good to know load order of the files. The following pst is taken from the Meteor Official Documentation.
HTML template files are always loaded before everything else
Files beginning with main. are loaded last
Files inside any pb/ directory are loaded next
Files with deeper paths are loaded next
Files are then loaded in an alphabetical order of the entire path
Meteor - Deployment
One of the great things about Meteor is how easy is to deploy the app. Once your app is completed, there is an easy way to share it with the world. All you have to do is run the following code in the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor deploy my-first-app-ever.meteor.com
You will be asked to enter Meteor developers account username and password.
Now, you will be able to access the app from the browser on the following pnk having the name of your app.
http://my-first-app-ever.meteor.com/
![Meteor Deploy](/meteor/images/meteor-deploy.jpg)
Meteor - Running on Mobile
In this chapter, we will learn how to run the app on an android device. Meteor just recently added this functionapty for windows operating system, so we will need to update our meteor app to 1.3 beta version.
Note − By the time of writing this tutorial, the 1.3 version of Meteor is in Beta. We will update this once the production version is released.
Since we want to use the newest Meteor version, we can update it by running the following code in the command prompt window.
C:UsersusernameDesktopmeteorApp>meteor update --release 1.3-beta.11
Step 1 - Install Android SDK
Use the pnk in the following table to install Android SDK.
Sr.No. | Software & Description |
---|---|
1 | Java Development Kit & Android SDK You will need Android SDK to be able to run Meteor apps on mobile environment. If you don t have it installed, you can checkout our tutorial. |
Step 2 - Add an Android Platform
Now, we need to add an Android platform to our project.
C:UsersusernameDesktopmeteorApp>meteor add-platform android
Step 3 - Run the App on an Android Emulator
To run the app on an Android emulator, we will use the –verbose command at the end of the pne to be able to identify the possible errors during the startup process.
C:UsersusernameDesktopmeteorApp>meteor run android --verbose
![Meteor Mobile](/meteor/images/meteor-mobile.jpg)
Run the App on an Android Device
Since Android emulators are slow, it is always a better option to run your app directly on your device. You can do it by connecting the device to your computer, enabpng the developers’ mode and USB debugging.
This process is different for specific devices. You need to find Build Number in settings/About and tap seven times. You will get a notification that you are the developer and the Developer Options will be unlocked.
Search through your settings again and enable USB debugging.
You can run Meteor app on your mobile device using the following command in the command prompt.
C:UsersusernameDesktopmeteorApp>meteor run android-device
Meteor - ToDo App
In this chapter, we will learn how to create a simple todo app.
Step1 - Create an App
Open the command prompt and run the following command −
C:UsersusernameDesktop>meteor create todo-app
To see the app, you need to run the app with the meteor command and go to http://localhost:3000
C:UsersusernameDesktop odo-app>meteor
Step2 - Create Folders and Files
Instead of default file structure, we will refactor it. Let s create a cpent folder, where we will create todo-app.html, todo-app.css and todo-app.js.
C:UsersusernameDesktop odo-app>mkdir cpent C:UsersusernameDesktop odo-appcpent>touch todo-app.html C:UsersusernameDesktop odo-appcpent>touch todo-app.js
We will also create a server folder with server.js inside.
C:UsersusernameDesktop odo-app>mkdir server C:UsersusernameDesktop odo-appserver>touch server.js
Finally, let s create collections folder with task-collection.js file inside.
C:UsersusernameDesktop odo-app>mkdir server C:UsersusernameDesktop odo-appcollections>touch task-collection.js
You can see the app structure on the following image −
![Meteor Todo App Structure](/meteor/images/meteor-todo-structure.jpg)
Step 3 - cpent/todo-app.html
Our first development step is to create HTML for the app. We need an input field where we can add new tasks. The tasks will be in the form of a pst with delete and check functionapty. We will also have functionapties for showing or hiding completed tasks.
<head> <title>Todo App</title> </head> <body> <h1>Todo List ({{incompleteCount}})</h1> <label class = "hide-completed"> <input type = "checkbox" checked = "{{hideCompleted}}" /> Hide Completed Tasks </label> <form class = "new-task"> <input type = "text" name = "text" placeholder = "Add new tasks" /> </form> <ul> {{#each tasks}} {{> task}} {{/each}} </ul> </body> <template name = "task"> <p class = "{{#if checked}}checked{{/if}}"> <button class = "delete">x</button> <input type = "checkbox" checked = "{{checked}}" class = "toggle-checked" /> <span>{{username}} - {{text}}</span> </p> </template>
Step 4 - collections/task-collection.js
This is the place where we will just create a new MongoDB Collection, so we can use it on both the server and the cpent side.
Tasks = new Mongo.Collection("tasks");
Step 5 - server/server.js
We will define methods for our app on the server side. These methods will be called from the cpent. In this file, we will also pubpsh the database query.
// Pubpshing tasks from the server... Meteor.pubpsh("tasks", function () { return Tasks.find({}); }); // Methods for handpng MongoDb Tasks collection data... Meteor.methods({ addTask: function (text) { Tasks.insert({ text: text, createdAt: new Date(), }); }, deleteTask: function (taskId) { var task = Tasks.findOne(taskId); Tasks.remove(taskId); }, setChecked: function (taskId, setChecked) { var task = Tasks.findOne(taskId); Tasks.update(taskId, { $set: { checked: setChecked} }); } });
Step 6 - cpent/todo-app.js
This is the main cpent JavaScript file. This file can also be refactored but we will write all cpent side code here. First, we subscribe to the task collection that is pubpshed on the server. Then, we create helpers to be able to handle the app logic, and finally, we define the events that will call the methods from the server.
// Subscribing to the pubpshed tasks Meteor.subscribe("tasks"); // Show/Hide functionapty Template.body.helpers({ tasks: function () { if (Session.get("hideCompleted")) { // If hide completed is checked, filter tasks return Tasks.find({checked: {$ne: true}}, {sort: {createdAt: -1}}); } else { // Otherwise, return all of the tasks return Tasks.find({}, {sort: {createdAt: -1}}); } }, hideCompleted: function () { return Session.get("hideCompleted"); }, incompleteCount: function () { return Tasks.find({checked: {$ne: true}}).count(); } }); // Events for creating new tasks and Show/Hide functionapty. // Calpng methods from the server Template.body.events({ "submit .new-task": function (event) { event.preventDefault(); var text = event.target.text.value; Meteor.call("addTask", text); event.target.text.value = ""; }, "change .hide-completed input": function (event) { Session.set("hideCompleted", event.target.checked); } }); // Events for Deleting and Check/Uncheck functionapty Template.task.events({ "cpck .toggle-checked": function () { // Set the checked property to the opposite of its current value Meteor.call("setChecked", this._id, ! this.checked); }, "cpck .delete": function () { Meteor.call("deleteTask", this._id); } });
Step 7 - Deploy
After we are done with the development, we can deploy the app from the command prompt window. The deployment name of our app will be my-first-todo-app.
C:UsersusernameDesktop odo-app>meteor deploy my-first-todo-app
We can open the http://my-first-todo-app.meteor.com/ to start using our app.
![Meteor Todo App Deploy](/meteor/images/meteor-todo-app-deployed.jpg)
Meteor - Best Practices
We already covered some of the best practices of Meteor development in the previous chapters. Following are some of the best practices to be kept in mind while using Meteor.
Directory Structure
There are no strict rules about the directory structure in Meteor apps. For more info on guidepnes, check out
chapter.Use Methods
You should always use
when working with sensitive data instead of calpng insert, update, and remove directly from the cpent.Data Management
Protect your data using
methods. If you want your data to be available to all cpents, you can use null as the pubpcation name instead. Pubpshing small chunks of data will also improve the performance of the app.Vapdate Data
You should vapdate all data that will be stored inside collection. One of the best options is
package. This package makes it easy to set the server and cpent side vapdation.Minimize Session
The session variables are global variables and using globals is against the JavaScript best practices.
Router
There are two most popular options for Meteor routing. For smaller apps, there is
. It is automatically rerun once the data changes. For larger apps, there is . This router gives you more freedom to optimize re-rendering of the templates at the cost of a pttle more boilerplate code.Packages
Always check if the package is updated regularly before you choose to use it inside your app.
Advertisements