MeteorJS. Google Maps integration

Imagine that you need to share some information from any path that you made in one map.

Google Maps allows you to draw it in a great way: You can just pick your set of waypoints, create a path using Directions with them and off you go!

But, what about sharing?

With MeteorJS, we have the ability to sync and present this data in real time to all clients connected to our service.

Combining MeteorJS potential and Google Maps possibilities it's easy to implement one way to draw and display your path to all users in only a few lines like this:

  Coords = new Meteor.Collection("Coords");

  pointsArr = new Array();

  var allCoords = Coords.find();
  allCoords.forEach(function (coord) {
    // Add coordinates into the array
    var latlng = new google.maps.LatLng(coord.lat, coord.lng);
    pointsArr.push(latlng);
  });

  var origin = pointsArr[0];
  var end = pointsArr[pointsArr.length - 1];
  var waypointsArr = new Array();
  if (pointsArr.length > 2) {
    pointsArr.forEach(function (item) {
    if (origin != item && end != item) {
        waypointsArr.push({'location': item});
    }
  });

For now we have declared one Meteor 'Collection' to store all selected points as coordinates, we use this information to draw the path in the map web as soon as our page is loaded.

Then we add some code to add a point from the map into this collection whenever we detect a click event on it.

Hey, this is not reactive!

But wait, there's a problem: We have ready a little demo which can store paths and display them in your browser, but it's not reactive yet so the other clients can't get the updates!

The main reason for it is this information is stored in the database but it must be sent to other clients to be drawn in their browsers. But we are almost there: It's now when Meteor Tracker comes to help:

  Tracker.autorun(function () {
    if (Coords.find().count()) {
      var allCoords = Coords.find();

      pointsArr = new Array();
      allCoords.forEach(function (coord) {
        // Add coordinates into the array
        var latlng = new google.maps.LatLng(coord.lat, coord.lng);
        pointsArr.push(latlng);
      });
      // Draw path in the map
      drawPath();
    }
    else {
      // To clear
      if(directionsDisplay) {
        directionsDisplay.setMap(null);
        directionsDisplay.setPanel(null);
      }
    }
  });

Tracker allows us to put some code into the autorun callback. This code is executed whenever a change happens, and it's in there where we have to call our function to redraw the path using the new dataset we just were notified about.

Now we have a reactive interface to share paths with Google Maps in real time using only a few lines of code. Great stuff! Thank you Meteor!

2 great frameworks to write HTML5 games

Gullon Dragons Game

Writing a HTML5 game to target multiple platforms, browsers, small and big screens is a great adventure. In 2014 there are multiple choices to achieve that, and this article will describe one of them.

Choose a framework

As of 2014, there are multiple frameworks, and picking one is not as easy as it seems. I will describe two popular HTML5 frameworks for building games: Quintus and Phaser.

Quintus

Quintus is an easy-to-learn, fun-to-use JavaScript HTML5 game engine for mobile, desktop.

Documentation

The best way to get started with Quintus is to read through the guides to get an understanding of the engine and the philosophy behind it.

Community

Currently, there are 802 stars, 252 forks, and 94 watchers on Github, and issues are actively processed: 16 open and 58 closed one.
Quintus Github

Phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
Phaser

Documentation

Documentation is quite extensive, also there is a great set of Phaser examples with the source code, so you can learn by example.

Community

Comparing to Quintus, Phaser is more active project, as currently there are 489 watchers, 5600 stars, 1726 forks, 64 opes issues, and 556 closed one on the Github.

Adding juice

No matter which framework you use, to make game that is fun to play, you have to make them juicy. But what is juiciness and how you can accomplish it? Martin Jonasson & Petri Purho describe a juicy game in the talk as follows:

Further reading:

Real-time drawing app with MeteorJS and SVG

Real time collaboration

There are a lot of discussion about real-time web these days. The tools are already here: web sockets, Node.js, Meteor...

Real-time drawing demo

Here is a small glimpse of these possibilities: no external plugins required, just a modern browser, desktop or mobile:

http://draw.avrora.io/

Try to open this link it two different windows, or in mobile and in the desktop, and try to write something. You will notice that every change is propagated immediately on the every screen, desktop or mobile.

Hint: double-click erases the board.

How it works: Meteor Reactivity

Real-time updates are implemented using the core feature of Meteor: reactivity, and is explained in depth in Chris Mather Reactivity with Contexts lesson.

In short, Meteor makes realtime the default - when data changes in your database, everybody's web UI updates automatically without you having to write additional code. How the real-time stack works internally in Meteor, and how MongoDB supports this feature, is well explained in David Glasser Next steps in scaling Meteor talk:

Drawing - SVG

Drawing mechanism is implemented using SVG, which as a vector image format, is well suited to draw graphics that can scale infinitely and plays very well with the responsive design approach. You can find more information about SVG on Learn SVG resourse.

Summary

That was a demo of a Meteor application, written in Javascript, which runs on Node.JS and stores data in MongoDB.

Logging in Meteor: from local file to the cloud

If you have to log useful data in Meteor, you have different options: starting from collecting standard/error output, using winston or logging to the cloud service, like Loggly.

Logging from Meteor's infrastructure

The fastest way to deploy Meteor app is to use meteor deploy <site>. In this case, command meteor logs <site> retrieves the server logs for the requested site. However, if you want more control, or you need to deploy on your own server, there are different options.

Logging from your own server

If you bundle your Meteor application and run it directly from Node (this process is well explained in one of the screencast from Chris Mather @EventedMind, you might use forever to keep the process run forever. In this case, forever logs command will list log files for all forever processes, and forever logs <script|index> will tail the logs for .

Logging to the cloud

There are plenty cloud-hosted logging providers: papertrail, splunk and loggly, to name just a few.

Using loggly module from Atmosphere, it's easy to start logging in no time to the Loggly:

  Logger = new Loggly({
  token: "your-really-long-input-token",
  subdomain: "your-subdomain",
  auth: {
    username: "your-username",
    password: "your-password"
  }
  });

  Logger.log("first log from meteor", "your-tag");

There is also set of useful methods to automatically attach tags to the log message:

  Logger.info("it will store this message with <info> tag");
  Logger.error("error with tag <error>");
  Logger.info("all", "arguments", "will be stored");
  Logger.info("my fancy object", {fancy: true});

Express 3.x to 4.0 migration

Express is a minimalist web development framework and one of the most popular modules for Node.js. The new 4.0 version of Express brings a better router and drops bundled middleware, so we decided to migrate from verstion 3.x to the newest version.

Changes

Express 4 does not depend on middleware framework connect anymore, which means that middlewares like bodyParser, session, favicon are not longer explicitly available. Instead, creators of the framework moved the middlewares to separate modules to improve their release cycle without affecting main express release. Most of these middlewares are ports from connect 2.x equivalents.

You have to add these new modules to package.json and require them in the code explicitly.

New stuff

Express brings a better router to make it easier to split routers into files/modules for project organization without sacrificing features like parameter matching.

In addition, app.route() method provides an instance of route, which can be used to call HTTP verbs on this or add middleware. A Router also could play a role of mini express application, providing typical routing APIs.

  app.route('/users')
  .get(function(req, res, next) {})
  .post(function(req, res, next) {}) 

Instead of causing a lot of issues app.router, now middleware and routes are executed in the order they are added in the source code.

To create a new app, use express(), because long deprecated express.createServer() does not exist anymore.

If you need to configure different routes based on environment, use if statement instead of app.configure().

  var env = process.env.NODE_ENV || 'development';
  if ('development' == env) {
      // configure stuff here
  }

References:

Server side user/password validation in Meteor

If you want to expose the data in your Meteor application to native mobile clients (iOS, Android, Windows Phone), you have at least two options:

1) Using DDP Client libraries to communicate through the Distributed Data Protocol protocol
2) Using REST API

Common use case is authenticating your clients. You can do it using DDP which is well explained, but if you want to implement authentication for your REST API, it's not so trivial, as there are no built-in mechanims to authenticate a plaintext password and username on the server side of Meteor app.

api-password module

We wrote a tiny Atmosphere module: api-password which could help to authenticate username and password on the server side.

Installation

meteor add miktam:api-password

Usage
  try {
    if (ApiPassword.isPasswordValid(username, password)) {
      console.log('password is valid for this user');
    } else {
      console.log('password is not valid');
    }

  } catch (exc) {
      console.log(exc.message);
      // 'User is not found', 'User has no password set', etc
  }

As soon as you securely send username and password to the server side (https would help), password validation is just calling of one method which returns Boolean. If user is not found, or the password for the user is not set, exception will be thrown.

References: