Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Build Applications with Meteor
Build Applications with Meteor

Build Applications with Meteor: Isomorphic JavaScript web development

eBook
$39.99
Paperback
$48.99
Subscription
Free Trial
Renews at $12.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Build Applications with Meteor

Chapter 1. Foundation of Meteor

Foundation of Meteor


Meteor is an open source web and mobile development platform, simplifying the process of building applications using only one programming language--JavaScript.

What is included in Meteor?

  • Server: As a full-stack platform needs a web server, Meteor runs on top of Node.js, and we get all the benefits of using the Node, such as non-blocking I/O event driven architecture, an enormous amount of open source packages via NPM, plus we don't need to switch the language from the backend to the frontend.
  • Database(s): Meteor comes with MongoDB in a universal way. We get a light copy of MongoDB on the browser called Minimongo. Both the databases are in sync in real-time out of the box, which means that the UI can be updated even before the data reaches the server, and that is one of the most compelling features of the platform.
  • Communication: How do the client and server talk to each other? The communication is done via DDP (Distributed Data Protocol), which is an RPC (Remote Procedure Call) protocol built on top of WebSockets instead of HTTP. Due to the bidirectional communication nature of the web sockets, Meteor is a real-time platform by default.
  • Frontend UI frameworks: Meteor was using Blaze as its primary template engine, which is Meteor's implementation of Handlebars; however, it also ships with support for Angular and React currently.

Now you must be wondering how all these technologies are glued together. On a very high level, the way Meteor works is that the server publishes channels and the client subscribes to those channels, then all updates from the client can update the server in real time and the other way around--updates on the server can update the client.

Now, let's look at what else is included in Meteor:

  • There is also a native for Meteor package management, called Atmosphere, where you can find tons of useful packages. Note that all Atmosphere packages will be moved to NPM in the future.
  • ECMAScript 6 or ES6 is the major upgrade of JavaScript language, and you can code in ES6 in any of your js files. There is no need for configuring anything like babel, webpack plugins, dev servers, and task runners.
  • Any changes on the server or the client create a build automatically for you, and there is no need for browser refresh or manual server restarts.
  • Throughout the book, we will be using React expect for Chapter 8Build a Chatbot with Facebook's Messenger Platform, where we will use Angular 2. With Meteor, there is zero effort to start writing React apps. There is no need for any babel presets or anything else. The support for JSX extension comes with the default ecmascript package.

In this chapter, we'll be looking at the following topics:

  • Downloading and installing Meteor
  • Installing packages with NPM and Meteor
  • Overview of React's API
  • Creating an example application with React and Meteor

Setting up the development environment


Installing and running Meteor is extremely easy.

For Linux and iOS, all you need is the terminal and cURL. cURL is basically a command-line tool that we can use to move data with URL syntax, such as a GET, POST, and more, all directly from the terminal.

For Windows users, Meteor comes with an installer. You can download it from https://www.meteor.com/install">https://www.meteor.com/install. All the commands in the book are executed in a Linux terminal; just skip the sudo command and execute the commands as administrator if you are on Windows.

If you don't have cURL installed, open your terminal and install it with the following commands:

  1. Run update as a superuser:
>> sudo apt-get update
  1. Install cURL:
>> sudo apt-get install curl
  1. Verify the installation:
 >> curl --version
  1. Once you have cURL installed, installing Meteor is easy as it's a one line command:
>> curl https://install.meteor.com/ | sh

This will download the latest version of Meteor, and it will install it globally on your machine. Node.js, NPM, MongoDB, and all other default packages will be inside the .meteor directory.

The final installation looks like this:

Meteor 1.4.4.2 has been installed in your home directory (~/.meteor).
Writing a launcher script to /usr/local/bin/meteor for your convenience.
This may prompt for your password.

In Chapter 9, Build Internet of Things Platform, we will build Node.js apps connecting to a Meteor app. If you don't have Node.js and MongoDB and you want to run them outside Meteor, here's a list of commands and installing scripts that you might find useful:

Install Node.js with cURL

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -

sudo apt-get install -y nodejs

Uninstall Node.js

sudo rm /usr/local/bin/{node,npm}

Update node with NPM

sudo npm cache clean -f sudo npm install -g n sudo n stable

Update to specific version with NPM

sudo n 4.4.4

Check the version of Node.js

node -v or node --version

Check the version of NPM

npm -v or npm --version

Install cURL and check its version

sudo apt-get update

sudo apt-get install curl

curl --versionc

Uninstall cURL

sudo apt-get remove --auto-remove curl

Purging cURL config data

sudo apt-get purge --auto-remove curl

MongoDB install(Ubuntu)

sudo apt-get update

sudo apt-get install -y mongodb-org

MongoDB version

mongod --version

Stop MongoDB

sudo service mongod stop

Restart MongoDB

sudo service mongod restart

Remove MongoDB

sudo apt-get purge mongodb-org*

Remove Data Directories

sudo rm -r /var/log/mongodb

sudo rm -r /var/lib/mongodb

The following are the Meteor scripts:

Install Meteor

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

Check the Meteor version

meteor --version

Update Meteor to the latest version

meteor update

Check the Node.js version in Meteor

meteor node -v

Create a Meteor App

meteor create app_name

Add an Atmosphere package to a Meteor app

meteor add package_name

Remove Atmosphere package

meteor remove package_name

List all the Atmosphere packages

meteor list

Install an npm package

meteor npm install package_name --save

List all the npm packages

npm list

Run a Meteor app on a specific port;

the default is 3000

meteor --port 2000

Launch the MongoDB shell in a meteor app

in the app directory execute meteor mongo

Show all databases from the MongoDB shell

show dbs

Switch to a database

use database_name

Show all collections in a database

show collections

Reset Meteor app

meteor reset

Building a Meteor app


The steps for creating a meteor app are as simple as the installation:

  1. Open your terminal and change your directory to where you want to have your app installed. With the meteor command line interface (CLI), we can create an app with just one command:
        >> meteor create <appname>

You can name it as anything you want; I am naming mine timerapp. We'll go through the steps of creating a basic timer, updating the time from the server side to the client in real time:

            >> meteor create timerapp

The meteor create appname command installed all packages and libraries specified in the .meteor folder in the app directory. In Meteor, the packages can be installed from Atmosphere and NPM, and there are two places where you can see what is installed by default.

Atmosphere packages are specified in ./meteor/packages. All native npm packages' metadata is in the package.json file.

FoldersIf you go into your app directory, you will note that Meteor created three folders and two files: client, server, .meteor, package.json, and .gitignore:

  • client: This is for all client-side code.
  • server: This is for all server-side code.
  • .meteor: This refers to all the core functionality of meteor: packages, databases, and many more.
  • package.json: This includes all NPM installed and saved packages.
  • .gitignore: This will ignore before the commit the specified files.
    1. cd to that app directory:
            >> cd timerapp

    To start the server, run the following command:

            >> meteor

    After some installation logs in the terminal, you'll see something like this:

            => Started proxy.
            => Started MongoDB.
            => Started your app.
            => App running at: http://localhost:3000/

    Note

    You can also start the app with npm start. This will execute the start script from package.json. "scripts": {"start": "meteor run"}. You can start meteor in another port by passing port as argument, for example, $ meteor --port 2000 . in case you have the 3000 port in use.

    1. Open the project in any text editor of your choice.

    In my setup, I am using Atom https://atom.io/ with the Facebook package Nuclide https://nuclide.io/. There are other very good editors, such as Sublime Text, Visual Studio Code, WebStorm, Brackets, and many more.

    The app skeleton, created by default, is nice and minimal. In the client and server folders, there is a startup JS main.js file. All this comes by default, and you do not need to create additional configs, specify entry points of the application in different environments, dev servers, plugins, and so on.

    The frontend with React


    The best way to start with React is by modifying and extending a Hello World example. There is a basic template available in the Facebook documentation.

    For simplicity, you don't need a server to get started with React; you can load it and explore it as an HTML document by opening it in your browser.

    Create a basic HTML page and place the scripts into the head tag:

    <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
      <script 
    
    src="https://unpkg.com/react@latest/dist/react.js">
      </script>
      <script 
    
    src="https://unpkg.com/react-dom@latest/dist/
      react-dom.js"></script>
      <script 
    
    src="https://unpkg.com/[email protected]/
      babel.min.js"></script>
    </head>

    With the preceding scripts, we loaded react and react-dom and the third script--babel--will make (transpile) our ES6 and JSX scripts compatible with the browsers.

    Also, we can render our first component in the body tag:

    <body>
    <div id="root"></div>
    <script 
    
    type="text/babel"> //this will make ES6 code and React Jsx compatible with the browser.
    
    
    ReactDOM.render(<h1>Hello, world!</h1>, 
       document.getElementById('root'))
    </script>
    </body>

    There are two ways to define components in React: as plain JavaScript functions or as an ES6 class that extends from React.Component.

    Let's look at a basic ES6 class component:

    class Greeting extendsReact.Component
    
    {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
     }
    }

    In the preceding code, we have an ES6 class Greeting that extends from React Component class; then we defined a render method that returns HTML tags. HTML tags in JavaScript is the special thing that comes with React. In essence, it is JavaScript XML (JSX) that Facebook added to React to make it more descriptive, and it also saves typing.

    You can use plain JavaScript but many developers, including myself, find it actually easier to write HTML into the JavaScript.

    Next, paste the Greeting component just above the ReactDOM.render line:

    class Greeting extends React.Component {
    render() {
        return <h1>Hello, 
    
    {this.props.name}</h1>;
      }
    }
    ReactDOM.render(
      <h1>Hello, world!
    
    </h1>,document.getElementById('root')
    )

    If you save your file and refresh your browser, you'll see that nothing changed. To render a component, you need to attach it to an actual DOM element or add it to a parent component that can render it.

    The idea of React is that we can build components or blocks and put them together to assemble complex user interfaces. Another thing you may find different is that the data flow between components is not that well prescribed like other frameworks. React itself has no actual strict pattern on how that should be done.

    However, the intention is to have the data always flowing from top to bottom in one direction, or unidirectionally as many refer to it, like a waterfall. Top-level components can pass data to their child components in one direction; if you want to update the data of a child component, you'll need to update it in the parent and pass it down again. Let's see how this works.

    Here's how we can render the Greeting component that we created:

    ReactDOM.render(
    
    
    <Greeting name="Joe"/>,document.getElementById('root')
    );

    We added the Greeting component as a <Greeting/> element, and we also passed a parameter, called name, with the value Joe.

    Save the document, refresh the browser, and see what it does.

    The properties or the props in the components are the way we pass data to components and the parameter name is accessible from the Greeting component as this.props.name.

    If we want to render many instances of the Greeting component, for example, we need a parent component that can render multiple child Greeting components:

    class App extends React.Component {
      constructor(props) {
      super
    
    (props);
      console.log(props); // array of three children components
    }
    render() {
    
    
    return (
       <div>
         {this.props.children} // render the children components
    
    
    </div>)
      }
    }
    const Greeting = ({ name}) => (
      <div>{name}
    
    </div>
    )

    Here the parent App component wraps and renders many children Greeting components:

    ReactDOM.render(
     <App>
         <Greeting
    
    name="Joe"/>
         <Greeting name="Tony"/>
         <Greeting name="Harry"/>
    
    
    </App>,document.getElementById('root'))

    The React's state

    Besides the flexibility of decoupling your development with reusable components, another powerful feature of React is in its component state. Every React component comes with an internal state.

    If the state of a component changes, the render method will fire and re-render the component. One thing that's very different from other frameworks is that React will re-render only the changes and nothing else.

    Also, it does so in a very efficient way, and it doesn't have to touch the DOM for searching before making any changes. What is happening in the back is that JSX actually represents the DOM in JavaScript, and all the updates are happening on the script site in memory first; then it will do some checks, then batch the changes and, finally, it will commit them to the DOM.

    Adding state to a stateless function component

    What is a state in React's components?

    Components can be declared as pure JavaScript functions, and they are called Stateless, such as this one:

    function Greeting({ hello }) {
          return <div>{hello}</div>;
    }
    

    Alternatively, you can write the preceding code as an ES6 arrow function:

    const Greeting = ({ hello }) => (
        <div>{hello}</div>
    )

    Every component can hold internal encapsulated data, and we call this a state of the component. If you want to add a state to a stateless component, you should define it as an ES6 class.

    Before adding an ES6 constructor and super methods to the stateless components, we can overview what an ES6 constructor is and what the super method does in ES6 classes.

    In ES6, we can create a class, such as the following:

    class Component {
    constructor(props){
       this.props = props;
      }
    }

    The names of the parameters and methods are named as React's once. This is not from the React library source.

    We can add a method called render, as mentioned in the following code:

    class Component {
       constructor(props){
       this.props = props;
    },
    
    render() {
       return this.props;
      }
    }

    In an ES6 classical way, we can extend the base/parent class Component:

    class Greeting extends Component{
    constructor(name){
        super(name) // passing the value to the parent class which gets
        assigned to the props
        console.log(super.render()) // with the super method we can call the  functions from the parent class      
        console.log(this.render()) // or directly as this.render
    }
    }

    In a classical way, we can create a new instance of the Greeting class, like this:

    let greet = new Greeting('Joe');
    console.log(greet.render()) // have an access to the parent method render

    We can create a render() method with the same name in the child class:

    class Greeting extends Component{
         constructor(name){
         super(name)
         this.name = name;
         console.log(super.render())
    }
     render() {
       return 'Hi ' + this.name;
      }
    }
    let greet = new Greeting('Harry');
    console.log(greet.render()) // child overrides the parent

    Inheritance versus composition

    Facebook and the React community encourage the use of composition over classical inheritance. It can be said that any other pattern to reuse code is considered anti-pattern in React. A lot more can be said about that, but React has been heavily used in production at Facebook without using inheritance for sure. In such a large-scale application, the advantage of building independent pieces and combining them to form a complex functionally is what made React so popular. Components can be moved around, organized by common functionality; they can be well tested and refactored without much of a risk of breaking other parts of the system.

    Extending from the React.Component:

    class Greeting extends
    
    React.Component {
      constructor(props){ // ES6 class constructor
      super(props) // ES6
     }
      render() {
       return <h1>Hello, {this.props.name}</h1>; //local
      }
    }

    Instead of creating a new Greeting instance, we are adding it as a <Greeting/> tag:

    ReactDOM.render(
    <Greeting name="Johny"/>,document.getElementById('root'))

    Some components can be strictly presentational; others may not know who can be their children components in advance. Many namings later came from the community, Smart and Dumb components, Containers and Components, functional and classical.

    How React is used it's all up to the developers, the team, and the organization. It's a very powerful and unopinionated library and can be used along with other frameworks.

    Adding a state to a component

    One can say that React barely has any API. It has about 9-10 methods and that is all we get.

    The State is one of the main APIs in React. The best place to define the initial state of a component is in the class constructor.

    Create a class component and initialize its state:

    class Button extends React.Component 
    
    {
       constructor(props){
       super(props)
    this.state = {text: 'OFF'}
       this.handleClick = this.handleClick.bind(this)
    }
      handleClick(){
    this.state.text === 'OFF' ? this.setState({text: 'ON'}) :
    this.setState({text: 'OFF'})
    }
     render() {
      return (
        <button type="button" onClick={this.handleClick}>
      {this.state.text}</button>)
      }
    }

    This is an example of an internal state of a button that changes its text on user click (it toggles between ON and OFF).

    A few things are required for that component to maintain a state:

    • We defined the state in the class constructor method. This is the first entry of the class that will be executed. We can think of that definition as the default state of the component.
    • We created a handleClick() method and bound it to the this class in the class constructor. It will fire when the user clicks on the button.
    • In the handleClick method, we used one of the React's APIs--this.setState--and based on the comparison of the current state, we set our new state.

    Note

    React is built with functional purity in mind, and if you set the state directly as this.state.text = 'OFF', the component will not re-render.

    • In the button, we added a simple JavaScript event--onClick. Here, React has a slightly different syntax on events; it uses camel case. onClick becomes onClick.

    The second form of the setState() method is passing a function in the state instead of an object; in the callback, we get the previous state:

    this.setState
    (function(prevState) {
    return {
       text: prevState.text === 'OFF' ? 'ON' : 'OFF'
      };
    });

    Alternatively, an arrow ES6 function can be used:

    this.setState((prevState) => ({
      text: prevState.text === 'OFF' ? 'ON' : 'OFF'
    }));

    Other React methods.

    A few other important React APIs are the component life cycles methods:

    class Greeting extends React.Component {
        constructor(props) {
        super(props);
        console.log('constructor');
    }
    componentDidMount() {
       console.log('componentDidMount');
    }
    componentWillUnmount() {
       console.log('componentWillUnmount');
    }
    render() {
       return (
       <div>
          <p>{this.props.name}</p>
            {this.props.children}
       </div>)
     }
    }

    Let's test these life cycle methods by adding a simple button to the body of the HTML:

    <button onclick="umountComponent()">Unmount</button>

    Also, we can define that function in the JavaScript tag, as follows:

    function umountComponent(){
    ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    }

    When the app is loaded, the order of the events is as follows:

    1. Constructor method is called.
    2. componentDidMount() is called when the component is mounted to a parent or directly to the DOM.
    3. componentWillUnmount() is called just before the component will unmount from the DOM.

    A simple use of these events can be as shown:

    1. Constructor: Initialize the component's default state in the constructor.
    2. componentDidMount(): The component is ready. You can perform any actions at that point.
    3. componentWillUnmount(): The component will be detached from the DOM; here, you can clear any resources that may cause memory leaks.

    Meteor with React

    Starting from the client, let's create our simple app:

    1. Delete all the content of the client folder.
    2. Create the index.html file with the following content:
    <head>
       <title>Timer</title>
    </head>
    <body>
      <div id="root"></div>
    </body>
    1. Meteor will take care of the missing HTML tags. It will compile it as a template rather than serve it as an HTML document.
    2. It will throw an error if you try to add the <!DOCTYPE html> and html> tags:
          While processing files with <cdpcomment data-comment-id="2521" 
          data-comment-text="Sounds incomplete. ">">templating-compiler 
          (for target web.browser):
    
          client/index.html:1: Expected one of: <body>, <head>, <template>.

    Since we are using only React, we don't need to have the blaze-html-templates package installed.

    Adding and removing atmosphere packages in Meteor

    There are two ways to add and remove atmosphere packages in Meteor: directly add it in .meteor/packages or use the meteor add or meteor removecommands.

    We will remove blaze and jquery for this example:

    >> meteor remove blaze-html-templates

    This will result in the following terminal:

    blaze-html-templates removed from your project
    caching-compiler removed from your project
    caching-html-compiler removed from your project
    templating removed from your project
    templating-compiler removed from your project
    templating-runtime removed from your project
    templating-tools removed from your project

    Now if you run your app, you will note that nothing is loaded. You'll need to install the html-static package to let Meteor load a static HTML file.

    You can install it with the following command:

    >> meteor add static-html

    It will add all the needed dependencies:

    caching-compiler added, version 1.1.8
    caching-html-compiler added, version 1.0.7
    static-html added, version 1.1.13
    templating-tools added, version 1.0.5
    Remove Jquery by deleting it in the package file (.meteor/packages)
    [email protected] # Helpful client-side library

    You can add and remove packages even if the server is running. Meteor will restart it automatically when a package is removed or added.

    The next step is directories and files:

    • Create index.js in the root of the client folder. This will be our start up file where we can import and render the rest of the components.
    • Create the components folder. For a small demo app like this, we can keep the components in a folder components.
    • In folder components, create a Timer.js file, you can use and also Timer.jsx; Meteor will transpile JSX into JavaScript by default. Both ways are fine.

    Install react and react-dom with npm:

            >> npm install react --save
            >> npm install react-dom --save

    In the Timer.js file, let's define our component:

    import React from 'react';
    import ReactDOM from 'react-dom';
    class Timer extends React.Component {
      constructor(props) {
      super(props);
    }
    render() {
      return (<div>
             <p>Timer</p>
             </div> )
      }
    }
    export default Timer;

    It is a class component that will display the time pushed in real time from the server. The only difference between preceding examples and this one, is that we exported that component to use it in other components.

    Now, let's import and render it in the index.js file:

    import React from 'react';
    import {render} from 'react-dom';
    import Timer from './components/Timer'
    render(<Timer/>, document.getElementById('root'))
    
    

    First, let's create the functionality of the app on the client; then we can start pushing the data from the server.

    Initialize the state in the constructor and set a new state every second:

    constructor(props) {
       super(props);
    this.state = {time: 0};
    } 
      componentDidMount() {
    setInterval(() => this.setState({time: new Date().toLocaleString()}), 1000);
    }

    Also, we have the following code in the render() method:

    render() {
        return (<div>Time : 
    {this.state.time}</div>)
       }

    When the component mounts, we set a new state every second. This will force the component to re-render and display the latest state.

    To exercise the idea of the state and the props, we can now create a child component that the Timer component will render and pass its state as prop.

    Create a child component in the components folder, called TimerDisplay:

    class TimerDisplay 
    extends React.Component {
        constructor(props) {
         super(props);
      }
     render() {
        return 
        (
           <div>Time : {this.props.time}</div>
        )
       }
    }
    export default TimerDisplay;

    The TimerDisplay will receive and render the data through the props.time. It can be a stateless presentational component, and it can be defined as a function instead of a class:

    import TimerDisplay from './TimerDisplay';
    class Timer extends React.Component {
       constructor() {
       super();
    this.state = {time: new Date().toLocaleString()};
    }
       componentDidMount() {
    setInterval(() => this.setState({time: new Date().toLocaleString()}), 1000);
     }
     render() 
    {
       return (
       <div>
       <TimerDisplay time={this.state.time}/>
    </div>)
      }
    }
    export default Timer;

    Here, the parent component, Timer, re-renders every time its state changes, and then renders the child component, TimerDisplay, by passing its state as props.

    What will happen if we add another TimerDisplay, but this time with a static value:

    render() 
    {
      return (
        <div>
         <TimerDisplay time={this.state.time}/>
         <TimerDisplay time='today'/>
      </div>)
    }

    To see the power of React in action, open the console in Chrome and press the Esc key then go to Rendering and click on the checkbox Paint Flashing. You will note that even if we rendered both TimerDisplay, only the one that has its value changed is re-rendering.

    Integrating React with Meteor's reactive data system

    In the preceding example, the data passed to the child component via props was generated in the parent component itself in the setInterval function. In order to render React components on Meteor's data change, we need to create a component container.

    The steps are as follows:

    1. Add react-meteor-data and react-addons-pure-render-mixin npm packages using the following command:
            >> npm install react-meteor-data --save
            >> npm install react-addons-pure-render-mixin --save
    1. Import createContainer into the Timer.js component:
            import React from 'react';
            import TimerDisplay from './TimerDisplay';
            import { createContainer } from 'react-meteor-data';
    1. Export the container function instead of the component:
            export default createContainer(() => {
            return {
               time: Time.find().fetch()
              };
            }, 
           Timer);

    The first parameter is a callback function that returns the result as an object named time, and the second parameter is the Timer component. The way it works is that on any changes in the browser database Minimongo, the data will be fetched and passed to the component as props (time in our case).

    To break this down, refer to this:

    1. We defined Time as a MongoDB collection.
    2. find() is a MongoDB method to query records (records are called documents in MongoDB) from the collection. If there is no query specified, will return cursor for the first 20 records by default.
    3. Adding the fetch() method will return the documents as an array.

    Meteor allows us to create a collection directly in the code:

    Time = new Mongo.Collection('time');

    Explore MongoDB in the Meteor shell

    You can access all the application data with the Meteor MongoDB shell.

    Open another terminal, cd to the app directory, and start the MongoDB shell.

    Note

    The app should be running at the same time.

    >> meteor mongo

    Show all the databases in MongoDB:

    >> show dbs

    The default database for the app is named meteor; switch to the meteor database:

    >> use meteor

    Display all collections in the database:

    >>show collections

    The show collections command will not return any results.

    The reason is that we created a collection on the client side only. This collection exists in Minimongo, and it is in the browser's memory. If we refresh the page, the collection and the data will be gone.

    In order to create the same collection and persist data into MongoDB, we have to execute the exact same Time = new Mongo.Collection('time'); on the server. As soon as we do that, both the collections will be in sync and the data will be persisted into the database.

    For now, we don't want to save the timer data on the server; we only want to take advantage of the Meteor server to client real-time communication.

    Publishing and Subscribing

    The way we can get real-time updates from the server is through the Publishing and Subscribing messaging pattern of Meteor.

    The server publishes an event and on the other side, the client subscribes to that event and listens to data changes.

    On the server, in our case in the server/main.js file, we can publish an event in a very simple way:

      import { Meteor } from 'meteor/meteor';
      Meteor.startup(() => {
         // code to run on server at startup
     Meteor.publish('time', function() {
         ...
        });
    });

    The publish function takes two arguments: name of the collection and a callback function that will be executed on each subscription from the client.

    On the client, we can subscribe to it as shown here:

    Meteor.subscribe('time');

    All updates from the server will push an update to Minimongo collection on the client. The subscriber can also pass a parameter as a second argument and/or have subscription handlers as callback functions:

    Meteor.subscribe('time', id);

    Also, the subscription handlers look like this:

    Meteor.subscribe('time', {
    
     //called when data is availble in  Minimongo
       onReady: function() {
       },
        // called on error
       onError: function() {
       },
       // called when the subcription is stopped. 
        onStop: function () {
       }
    });

    Here's the server-side code of the subscription:

    import { Meteor } from 'meteor/meteor';
    import { Random } from 'meteor/random';
    
    Meteor.startup(() => {
    // code to run on server 
    
    at startup
    Meteor.publish('time', function() {
       let self = this;
       const newTime = () => {
       let 
    
    id = Random.id();
       let time = {
        time: new Date().toString()
     }
       self.added
    
    ('time', id, time);
    }
    Meteor.setInterval(function() {
        newTime();
      }, 1000);
    });

    What we did is covered in the following points:

    1. We created a publisher with a collection called time.
    2. We used one of the Meteor's timer functions, setInteval(), to call a newTime() function every 1000 milliseconds or one second.
    3. In the newTime() function, we created an ID of the document and the document as the current time.
    4. We then called the added method, which will notify the subscriber that we added a new document to the time collection.

    The client-side code is as follows:

    Time = new Mongo.Collection('time');
    class Timer extends React.Component {
         constructor(props) 
    
    {
         super(props);
        Meteor.subscribe('time');
    }
    render() {
       return 
    
     <TimerDisplay time={this.props.time}/>;
      }
    }
    export default createContainer(() => {
     return 
    
    {
        time: Time.find().fetch()
      };
    }, Timer);

    This is what we did here:

    1. We created a collection called time. The collection is created locally in Minimongo. If we don't create the same collection on the server, it will be only in the browser's memory.
    2. In the class constructor, we subscribed to the dataset time published on the server.
    3. In the render method, we rendered the TimerDisplay component as we passed time as props.
    4. At the end, we created a Meteor React container that listens to data changes, fetches the latest data from the collection, and passes it down to the component as props.
    Improvements in the current code

    In both the server and the client, we didn't provide an unsubscribing mechanism. For example, if you close the browser, the server will continue calling the newTime() function indefinitely.

    Meteor.publish() provides some other useful APIs. When the client is subscribed for the first time, we can send a notification that the initial dataset was sent using this.ready(). This will call the onReady callback on the client.

    We can also unsubscribe the client with this.stop() or listen whether the client subscription is stopped.

    The publisher on the server:

    Meteor.publish('time', function() {
       let self = this;
       self.added('time', id, time); // notify if record is added to the collection time
      let interval = Meteor.setInterval(function() {
          newTime();
      }, 1000);
     this.ready(); // 
    
    notify that the initial dataset was sent
       self.onStop(function () {
       self.stop()
       console.log('stopped called')
       Meteor.clearInterval(interval); // clear the interval if the the client unsubscribed
      });
    });

    The subscriber on the client:

    const handle = Meteor.subscribe("time", {
       onReady: function() { 
    // fires when this.ready() called on the server.
      }
    });
     handle.stop() // will call onStop(callback) on the server.
     handle.ready() // returns true if the server called ready()

    The clientTimer component:

    Time = new Mongo.Collection('time');
    const handle = Meteor.subscribe('time');
    class Timer extends React.Component {
        constructor(props) {
        super(props);
     }
     shouldComponentUpdate() {
        return this.props.handle.ready() && this.props.time.length > 0;
     }
     componentWillUnmount() {
       this.props.handle.stop();
     }
     render() {
        return <TimerDisplay time = { this.props.time }/>;
     }
    }
    export default createContainer(() => {
      return {
        time: Time.find().fetch(), handle: handle
      };
    }, Timer);

    Here, we passed the subscriber's handle as a prop to the component and in shouldComponentUpdate, we check whether the publisher sent the first dataset and whether it has any records. If yes, it will render the imerDisplay component.

    When we unmount the component, we send a notification to the that we stopped the subscription.

    Summary


    We went over the foundation of Meteor and overviewed its core components. High-level databases, servers, package managers, and its communication protocol (Distributed Data Protocol). On a high level, we now understand how the platform works.

    We installed Meteor and created a sample app with the Meteor CLI. Then, we went over the default app skeleton and some of the included Atmosphere and NPM packages.

    On the frontend, we overviewed the basics of React, its data flow, and component architecture. Then, we created a sample real-time server to client communication app and got familiar with the core functionality of the Meteor Publish and Subscribing API.

    In the next chapter, we will get more familiar with the Meteor Methods, Schema, and validation by building a simple shopping cart app, and we will continue exploring data handling and reactive rendering with React on the frontend.

    Left arrow icon Right arrow icon

    Key benefits

    • Develop a set of real-world applications each exploring different features of Meteor
    • Make your app more appealing by adding reactivity and responsiveness to it
    • Work with the most powerful feature of Meteor—the “full stack reactivity”—through building real-time applications with many third party libraries

    Description

    This book starts with the basic installation and overview of the main components in Meteor. You’ll get hands-on multiple versatile applications covering a wide range of topics from adding a front-end views with the hottest rendering technology React to implementing a microservices oriented architecture.All the code is written with ES6/7 which is the latest significantly improved JavaScript language. We’ll also look at real-time data streaming, server to server data exchange, responsive styles on the front-end, full-text search functionality, and integration of many third-party libraries and APIs using npm. By the end of the book, you’ll have the skills to quickly prototype and even launch your next app idea in a matter of days.

    Who is this book for?

    If you are a developer who is looking forward to taking your application development skills with Meteor to next level by getting your hands-on different projects, this book is for you.

    What you will learn

    • * See how Meteor fits in the modern web application development by using its reactive data system
    • *Make your front-end behave consistently across environments by implementing a predictable state container with Redux
    • * Get familiar with React and overview of Angular 2
    • * Add a map to your application with a real-time geolocation
    • * Plugin into Meteor social media APIs like Twitter's streaming and Facebook's Messenger
    • * Add search functionality from scratch to your existing app and data
    • * Add responsiveness with Bootstrap 4 and Google's Material Design using Less and Sass
    • * Distribute your data across machines and data centers by adding Apache Cassandra to your existing stack.
    • * Learn how to scale your microservices with the high performant language neutral framework gRPC.
    • *Learn how to query multiple data sources using GraphQL.
    Estimated delivery fee Deliver to United States

    Economy delivery 10 - 13 business days

    Free $6.95

    Premium delivery 6 - 9 business days

    $21.95
    (Includes tracking information)

    Product Details

    Country selected
    Publication date, Length, Edition, Language, ISBN-13
    Publication date : May 30, 2017
    Length: 388 pages
    Edition : 1st
    Language : English
    ISBN-13 : 9781787129887
    Languages :
    Tools :

    What do you get with Print?

    Product feature icon Instant access to your digital copy whilst your Print order is Shipped
    Product feature icon Paperback book shipped to your preferred address
    Product feature icon Redeem a companion digital copy on all Print orders
    Product feature icon Access this title in our online reader with advanced features
    Product feature icon DRM FREE - Read whenever, wherever and however you want
    OR
    Modal Close icon
    Payment Processing...
    tick Completed

    Shipping Address

    Billing Address

    Shipping Methods
    Estimated delivery fee Deliver to United States

    Economy delivery 10 - 13 business days

    Free $6.95

    Premium delivery 6 - 9 business days

    $21.95
    (Includes tracking information)

    Product Details

    Publication date : May 30, 2017
    Length: 388 pages
    Edition : 1st
    Language : English
    ISBN-13 : 9781787129887
    Languages :
    Tools :

    Packt Subscriptions

    See our plans and pricing
    Modal Close icon
    $12.99 billed monthly
    Feature tick icon Unlimited access to Packt's library of 6,500+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Simple pricing, no contract
    $129.99 billed annually
    Feature tick icon Unlimited access to Packt's library of 6,500+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Choose a DRM-free eBook or Video every month to keep
    Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
    Feature tick icon Exclusive print discounts
    $179.99 billed in 18 months
    Feature tick icon Unlimited access to Packt's library of 6,500+ practical books and videos
    Feature tick icon Constantly refreshed with 50+ new titles a month
    Feature tick icon Exclusive Early access to books as they're written
    Feature tick icon Solve problems while you work with advanced search and reference features
    Feature tick icon Offline reading on the mobile app
    Feature tick icon Choose a DRM-free eBook or Video every month to keep
    Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
    Feature tick icon Exclusive print discounts

    Frequently bought together


    Stars icon
    Total $ 182.97
    React Native Blueprints
    $48.99
    Build Applications with Meteor
    $48.99
    Meteor: Full-Stack Web Application Development
    $84.99
    Total $ 182.97 Stars icon
    Visually different images

    Table of Contents

    9 Chapters
    Foundation of Meteor Chevron down icon Chevron up icon
    Building a Shopping Cart Chevron down icon Chevron up icon
    Style Your React Components with Bootstrap and Material Design Chevron down icon Chevron up icon
    Real-Time Twitter Streaming Chevron down icon Chevron up icon
    Developing Kanban Project Management Tool Chevron down icon Chevron up icon
    Building a Real-Time Search Application Chevron down icon Chevron up icon
    Real-Time Maps Chevron down icon Chevron up icon
    Build a Chatbot with Facebook’s Messenger Platform Chevron down icon Chevron up icon
    Build Internet of Things Platform Chevron down icon Chevron up icon

    Customer reviews

    Rating distribution
    Full star icon Full star icon Full star icon Full star icon Empty star icon 4
    (3 Ratings)
    5 star 66.7%
    4 star 0%
    3 star 0%
    2 star 33.3%
    1 star 0%
    Barnhardt Enterprises, Inc Nov 22, 2019
    Full star icon Full star icon Full star icon Full star icon Full star icon 5
    Very detailed and well written. This is a great reference for Meteor developers as well as beginners.
    Amazon Verified review Amazon
    Julien Jul 23, 2017
    Full star icon Full star icon Full star icon Full star icon Full star icon 5
    This book not only cover Meteor. You're going to learn how to develop professional app along to the best web technologies, from Bootstrap to gRPC.The first chapters are more about how Meteor works and deals with other libraries.Chapter after chapter, this book cover several technologies to help you choose the best ones for your needs.Actually this book is for both Meteor developers and full-stack web developer enthusiast.In spite of some typos, everything is clear and well explained. The book contains lots of exercises that you are encouraged to do to put in practice concepts previously seen.I'm happy to have this book in my library.
    Amazon Verified review Amazon
    Justin R McCormick Oct 17, 2018
    Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
    I bought this book off the 5-star review and figured it would jump start development with meteor. After going through the first few chapters, I am moving onto the next possible candidate. Most of the source code examples don't work, have typos, and missing end of lines. As well as the source examples being wrong, the source examples are not presented clearly by chopping newline's into the next line of the book etc. I'm not sure if this was a printing error, but it started to become a pain.Overall, this was a brief overview for different sections and I would continue reading if the examples weren't chopped & screwed (remix) in a way. After looking at other books, I clearly recommend going with something else. Just my two cents. Trying to save someone the time of buying this unless code examples that don't work will not bother you.
    Amazon Verified review Amazon
    Get free access to Packt library with over 7500+ books and video courses for 7 days!
    Start Free Trial

    FAQs

    What is the delivery time and cost of print book? Chevron down icon Chevron up icon

    Shipping Details

    USA:

    '

    Economy: Delivery to most addresses in the US within 10-15 business days

    Premium: Trackable Delivery to most addresses in the US within 3-8 business days

    UK:

    Economy: Delivery to most addresses in the U.K. within 7-9 business days.
    Shipments are not trackable

    Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
    Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

    EU:

    Premium: Trackable delivery to most EU destinations within 4-9 business days.

    Australia:

    Economy: Can deliver to P. O. Boxes and private residences.
    Trackable service with delivery to addresses in Australia only.
    Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
    Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

    Premium: Delivery to addresses in Australia only
    Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

    India:

    Premium: Delivery to most Indian addresses within 5-6 business days

    Rest of the World:

    Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

    Asia:

    Premium: Delivery to most Asian addresses within 5-9 business days

    Disclaimer:
    All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


    Unfortunately, due to several restrictions, we are unable to ship to the following countries:

    1. Afghanistan
    2. American Samoa
    3. Belarus
    4. Brunei Darussalam
    5. Central African Republic
    6. The Democratic Republic of Congo
    7. Eritrea
    8. Guinea-bissau
    9. Iran
    10. Lebanon
    11. Libiya Arab Jamahriya
    12. Somalia
    13. Sudan
    14. Russian Federation
    15. Syrian Arab Republic
    16. Ukraine
    17. Venezuela
    What is custom duty/charge? Chevron down icon Chevron up icon

    Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

    Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

    The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

    List of EU27 countries: www.gov.uk/eu-eea:

    A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

    How do I know my custom duty charges? Chevron down icon Chevron up icon

    The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

    For example:

    • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
    • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
    How can I cancel my order? Chevron down icon Chevron up icon

    Cancellation Policy for Published Printed Books:

    You can cancel any order within 1 hour of placing the order. Simply contact [email protected] with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at [email protected] using the returns and refund process.

    Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

    What is your returns and refunds policy? Chevron down icon Chevron up icon

    Return Policy:

    We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on [email protected] with the order number and issue details as explained below:

    1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on [email protected] within one hour of placing the order and we will replace/refund you the item cost.
    2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on [email protected] who will be able to resolve this issue for you.
    3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
    4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
    5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
    6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

    On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on [email protected] within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

    What tax is charged? Chevron down icon Chevron up icon

    Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

    What payment methods can I use? Chevron down icon Chevron up icon

    You can pay with the following card types:

    1. Visa Debit
    2. Visa Credit
    3. MasterCard
    4. PayPal
    What is the delivery time and cost of print books? Chevron down icon Chevron up icon

    Shipping Details

    USA:

    '

    Economy: Delivery to most addresses in the US within 10-15 business days

    Premium: Trackable Delivery to most addresses in the US within 3-8 business days

    UK:

    Economy: Delivery to most addresses in the U.K. within 7-9 business days.
    Shipments are not trackable

    Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
    Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

    EU:

    Premium: Trackable delivery to most EU destinations within 4-9 business days.

    Australia:

    Economy: Can deliver to P. O. Boxes and private residences.
    Trackable service with delivery to addresses in Australia only.
    Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
    Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

    Premium: Delivery to addresses in Australia only
    Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

    India:

    Premium: Delivery to most Indian addresses within 5-6 business days

    Rest of the World:

    Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

    Asia:

    Premium: Delivery to most Asian addresses within 5-9 business days

    Disclaimer:
    All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


    Unfortunately, due to several restrictions, we are unable to ship to the following countries:

    1. Afghanistan
    2. American Samoa
    3. Belarus
    4. Brunei Darussalam
    5. Central African Republic
    6. The Democratic Republic of Congo
    7. Eritrea
    8. Guinea-bissau
    9. Iran
    10. Lebanon
    11. Libiya Arab Jamahriya
    12. Somalia
    13. Sudan
    14. Russian Federation
    15. Syrian Arab Republic
    16. Ukraine
    17. Venezuela