Jasmine Tutorial: Unit Testing Promises In Services

Leave a comment Standard

So recently I’ve been doing a lot of Angular unit tests with Jasmine and Grunt. I have to say, testing promises is extremely frustrating and most of the examples I found out there either 1) didn’t work or 2) wouldn’t allow you to test content in a then block if you had multiple chained promises, or if you had a promise being called from and returned from another service. After many hours of frustrating trial and errors I found a solution I’m happy with so I want to share.

Let’s assume this is your controller:

'use strict';

angular.module('myModule').controller('myCtrl', ['$scope', 'api',
function ($scope, $api) {

  $scope.data = null;
  $scope.message = null;

  /**
  * Load some data from the API service
  * @return boolean
  **/
  $scope.loadData = function () {

    var config = {
      method: 'GET',
      url: 'http://api.domain.com/someRESTfulEndpoint',
      headers: {'Content-Type': 'application/json'},
      data: null
    };

    return $api.load(config).then(function (request) {
      if (request) {
        $scope.message = 'Your data was successfully loaded';
        $scope.data = request.response;
        return true;
      } else {
        $scope.message = 'The API service failed';
      }
      return false;
    });
  };
}]);

And here is the service making your API calls:

'use strict';

angular.module('myModule').service('api', ['$rootScope', '$http',
  function ($rootScope, $http) {

    /**
    * Makes the $http request given the proper configuration options
    * @param Object configruation for the $http request
    * @return Object $http promise that resolves to request payload or error
    **/
    this.load = function (options) {
      return $http({
        method: options.method || 'GET',
        url: options.url || 'http://api.domain.com/someDefaultEndpoint',
        headers: options.headers || null,
        data: options.data || null
      }).then(
        function (request) {
          //we got a response back, return just the API payload data
          if (request.status === 200 && request.data) {
            return request.data;
          } else {
            return {
              results: false,
              message: 'API request error',
              response: request
           };
         }
       }
     );
   };
}]);

Finally, this is your working unit tests:

'use strict';

describe('testing myModule', function () {

  beforeEach(module('myModule'));

  var $controller, $rootScope, $scope, $api, $httpBackend, $q;

  beforeEach(
    inject(function (_$controller_, _$rootScope_, api, _$httpBackend_, _$q_) {
      $controller = _$controller_;
      $rootScope = _$rootScope_;
      $httpBackend = _$httpBackend_;
      $q = _$q_;
      $api = api;
      $scope = $rootScope.$new();

      $httpBackend.when('GET').respond('test http GET call');
      $httpBackend.when('POST').respond('test http POST call');

      $controller('myCtrl', {
        $scope: $scope,
        $api: $api
      });
    })
  );

  it('has a $scope.loadData() function', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    var fakeData = { data: 'is fake' };

    //we spy on the API service and also return a fake promise call
    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({result: true, response: fakeData});
        return deferred.promise;
      });
    });

    $scope.loadData(testConfig); //call the function we're testing in the controller
    $scope.$apply(); //we have to call this so Angular will try and resolve the promise
    expect($api.load.calls.count()).toEqual(1); //make sure it's called the api service
    expect($scope.message).toEqual('Your data was successfully loaded');
    expect($scope.data).toEqual(fakeData);
  });

  it('returns an error if the API fails', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({
        result: false,
        message: 'api error'
      });
      return deferred.promise;
    });

    $scope.loadData(testConfig);
    $scope.$apply();
    expect($scope.message).toEqual('api error');
    expect($api.load.calls.count()).toEqual(1);
  });
});

 

Sample Angular Website

Leave a comment Standard

So I’ve seen a lot of people using AngularJS but I see very few examples of a website made using it. That’s why I decided to post an example website to give you an idea of what a full website looks like using AngularJS. It has samples of some of the things you’ll commonly find in a website made entirely with Angular:

  •  Navigation & Routing
  • Providers & Directives
  • Controllers & Config Blocks
  • Data Calculations
  • Filtering

Sorry if you’re looking for Angular 2.0, this was made with Angular 1.5.8. View, fork and/or edit the files on Plunker!

PHP Tutorial: Run Multiple Tic-Tac-Toe Game Instances (no database required)

Leave a comment Standard

Someone asked me about this in a comment recently so this post is specifically for you but I’m sure there are other people who will benefit from it as well. If you haven’t read the tic-tac-toe game tutorial yet then you’ll need to start there. This tutorial assumes you’ve already completed that and now you want to run two or more tic-tac-toe boards on the page simultaneously.

Or if you want to skip this tutorial you can
download the source code or try the working example

Concepts

The neat thing about classes is that you can use them to create multiple instances with varying states and data even though they all have the same methods and properties. Think about a monster RPG game. Each monster has a different name and breed and picture and strength — but they all have those things in common even though the values are different. Our tic tac toe class works the same way, we can create multiple instances of the game and they’ll each have different states — whose turn it is, which places on the board are filled — but they’ll all work the same way. In order to run multiple instances of our tic tac toe games we’re going to have to update our games so they can be uniquely identified by an instance number. The reason for this is so that when you play the game on instance 1 we know you want to update the state of instance 1 when you submit the form. If we didn’t give each game it’s own instance identifier then every time you made a move on one board it would reflect that move on all instances of the board at the same time.

Creating The Instance Form

Let’s change our index file so that we’re allowing the user to choose how many instances of the game they want to play. We start by removing where we created a new game from the top of the file. Since we want multiple instances we need to create the new game for every instance we have and since we don’t know how many instances we have at this point it needs to move down in our code base. Now once the user has selected how many instances of the game they want to play we need to dynamically generate that many. Using a for loop we loop through the number of instances they selected and create a game for each of those instances in our new $_SESSION[‘game’] array. Before this was only a single game, making it an array means we now have multiple games in our game session variable. Finally we create a new game instance and tell it to start playing. This is what our new index file looks like.

<?php
/***
* File: index.php
* Author: design1online.com, LLC
* Created: 4.6.2015
* License: Public GNU
* Description: PHP/MySQL Version of 2 Player Tic Tac Toe
* that allows playing multiple instances of the game at the same time
***/
require_once('oop/class.game.php');
require_once('oop/class.tictactoe.php');

//this will store their information as they refresh the page
session_start();

define('MAX_INSTANCES', 5); //the maximum number of games they can play at the same time

//trying to set number of instances to play
if (isset($_POST['instances'])) {
 if (is_numeric($_POST['instances']) && $_POST['instances'] > 0) {
 $_SESSION['instances'] = $_POST['instances'];
 }
}

?>
<html>
 <head>
 <title>Tic Tac Toe - Multiple Instances</title>
 <link rel="stylesheet" type="text/css" href="inc/style.css" />
 </head>
 <body>
 <div id="content">
 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
 <h2>Let's Play Tic Tac Toe!</h2>
 <?php
 //we need to know how many instances to create
 if (!isset($_SESSION['instances'])) {
 ?>
 <p>How many games would you like to instantiate?</p>
 <select name="instances">
 <?php
 for ($i = 1; $i <= MAX_INSTANCES; $i++) {
 echo "<option value=\"$i\">$i</option>";
 }
 ?>
 </select>
 <input type="submit" name="submit" value="Let Me Play!" />
 <?php
 } else {
 echo "<table width=\"100%\">
 <tr>";
 
 for ($i = 1; $i <= $_SESSION['instances']; $i++) {
 
 //if they haven't started a game yet let's load one
 if (!isset($_SESSION['game'][$i]['tictactoe'])) {
 $_SESSION['game'][$i]['tictactoe'] = new tictactoe($i);
 }
 
 echo "<td>";
 
 //play the game passing it the game data for that instance
 $_SESSION['game'][$i]['tictactoe']->playGame($_POST);
 
 echo "</td>";
 }
 
 echo "</tr>
 </table>";
 }
 ?>
 </form>
 </div>
 </body>
</html>

Adding Instances To The Class

The first thing we need to do is add an instance identifier to our tictactoe class. Since we need to know which game the player is trying to play adding a $this->instance value to our class will let us keep track of which game is which. Once that’s done we update our checks for $_POST data to make sure we’re using the correct data for the correct instance. Voila! Our games now only update when they see $_POST data that pertains to them. Our new tictactoe class file looks like this:

<?php
/***
* File: oop/class.tictactoe.php
* Author: design1online.com, LLC
* Created: 1.31.2012
* License: Public GNU
* Description: tic tac toe game
***/

class tictactoe extends game
{
 var $instance = 0; //the instance of this game
 var $player = "X"; //whose turn is
 var $board = array(); //the tic tac toe board
 var $totalMoves = 0; //how many moves have been made so far 

 /**
 * Purpose: default constructor
 * Preconditions: none
 * Postconditions: parent object started
 **/
 function tictactoe($instance)
 {
 /**
 * instantiate the parent game class so this class
 * inherits all of the game class's attributes 
 * and methods
 **/
 $this->instance = $instance;
 game::start();
 
 $this->newBoard();
 }
 
 /**
 * Purpose: start a new tic tac toe game
 * Preconditions: none
 * Postconditions: game is ready to be displayed
 **/
 function newGame()
 {
 //setup the game
 $this->start();
 
 //reset the player
 $this->player = "X";
 $this->totalMoves = 0;
 
 //reset the board
 $this->newBoard();
 }
 
 function newBoard() {
 
 //clear out the board
 $this->board = array();
 
 //create the board
 for ($x = 0; $x <= 2; $x++)
 {
 for ($y = 0; $y <= 2; $y++)
 {
 $this->board[$x][$y] = null;
 }
 }
 }
 
 /**
 * Purpose: run the game until it's tied or someone has won
 * Preconditions: all $_POST content for this game
 * Postconditions: game is in play
 **/
 function playGame($gamedata)
 {
 if (!$this->isOver() && isset($gamedata[$this->instance . 'move'])) {
 $this->move($gamedata);
 }
 
 //player pressed the button to start a new game
 if (isset($gamedata[$this->instance . 'newgame'])) {
 $this->newGame();
 }
 
 //display the game
 $this->displayGame();
 }
 
 /**
 * Purpose: display the game interface
 * Preconditions: none
 * Postconditions: start a game or keep playing the current game
 **/
 function displayGame()
 {
 
 //while the game isn't over
 if (!$this->isOver())
 {
 echo "<div id=\"board\">";
 
 for ($x = 0; $x < 3; $x++)
 {
 for ($y = 0; $y < 3; $y++)
 {
 echo "<div class=\"board_cell\">";
 
 //check to see if that position is already filled
 if ($this->board[$x][$y])
 echo "<img src=\"images/{$this->board[$x][$y]}.jpg\" alt=\"{$this->board[$x][$y]}\" title=\"{$this->board[$x][$y]}\" />";
 else
 {
 //let them choose to put an x or o there
 echo "<select name=\"{$this->instance}_{$x}_{$y}\">
 <option value=\"\"></option>
 <option value=\"{$this->player}\">{$this->player}</option>
 </select>";
 }
 
 echo "</div>";
 }
 
 echo "<div class=\"break\"></div>";
 }
 
 echo "
 <p align=\"center\">
 <input type=\"submit\" name=\"{$this->instance}move\" value=\"Take Turn\" /><br/>
 <b>It's player {$this->player}'s turn.</b></p>
 </div>";
 }
 else
 {
 
 //someone won the game or there was a tie
 if ($this->isOver() != "Tie")
 echo successMsg("Congratulations player " . $this->isOver() . ", you've won the game!");
 else if ($this->isOver() == "Tie")
 echo errorMsg("Whoops! Looks like you've had a tie game. Want to try again?");
 
 echo "<p align=\"center\"><input type=\"submit\" name=\"{$this->instance}newgame\" value=\"New Game\" /></p>";
 }
 }
 
 /**
 * Purpose: trying to place an X or O on the board
 * Preconditions: the position they want to make their move
 * Postconditions: the game data is updated
 **/
 function move($gamedata)
 { 

 if ($this->isOver())
 return;

 //remove duplicate entries on the board 
 $gamedata = array_unique($gamedata);
 
 foreach ($gamedata as $key => $value)
 {
 if ($value == $this->player)
 { 
 //update the board in that position with the player's X or O 
 $coords = explode("_", $key);
 
 //make sure we use the data from the right instance
 if ($coords[0] == $this->instance) {
 $this->board[$coords[1]][$coords[2]] = $this->player;

 //change the turn to the next player
 if ($this->player == "X")
 $this->player = "O";
 else
 $this->player = "X";
 
 $this->totalMoves++;
 }
 }
 }
 
 if ($this->isOver())
 return;
 }
 
 /**
 * Purpose: check for a winner
 * Preconditions: none
 * Postconditions: return the winner if found
 **/
 function isOver()
 {
 //top row
 if ($this->board[0][0] && $this->board[0][0] == $this->board[0][1] && $this->board[0][1] == $this->board[0][2])
 return $this->board[0][0];
 
 //middle row
 if ($this->board[1][0] && $this->board[1][0] == $this->board[1][1] && $this->board[1][1] == $this->board[1][2])
 return $this->board[1][0];
 
 //bottom row
 if ($this->board[2][0] && $this->board[2][0] == $this->board[2][1] && $this->board[2][1] == $this->board[2][2])
 return $this->board[2][0];
 
 //first column
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][0] && $this->board[1][0] == $this->board[2][0])
 return $this->board[0][0];
 
 //second column
 if ($this->board[0][1] && $this->board[0][1] == $this->board[1][1] && $this->board[1][1] == $this->board[2][1])
 return $this->board[0][1];
 
 //third column
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][2] && $this->board[1][2] == $this->board[2][2])
 return $this->board[0][2];
 
 //diagonal 1
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][1] && $this->board[1][1] == $this->board[2][2])
 return $this->board[0][0];
 
 //diagonal 2
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][1] && $this->board[1][1] == $this->board[2][0])
 return $this->board[0][2];
 
 if ($this->totalMoves >= 9)
 return "Tie";
 }
}

Conclusion

Try the working example! In this tutorial we talked about instances and how you can use a class to dynamically create multiple instances each of which keep track of their own state and values. If you’ve been following my game tutorials then I hope you’re starting to see how powerful classes are and how iterative improvements can be used to enhance your gameplay, functionality and user experience.

HTML5 Tutorial: Simple Music Player

Leave a comment Standard

So this is a pretty simple example but I was playing around with flash for my chat room and this was byproduct of that experimentation. It’s funny how even when I’m trying to learn something new I do my best to make it useful for other situations which is a good habit to get into if you’re not doing it already.

Try out the working demo or download the code

Caveats

This will only work on a browser that is HTML5 compliant and has support for audio. That means older browsers and most versions of Internet Explorer are not supported. Firefox, Chrome and Opera work as well as the newest versions of Internet Explorer.

The Audio Tag

If you’re familiar with HTML then most of the index file below will look pretty familiar. The thing you really have to pay attention to is the new <audio> tag. It looks like this:

<audio id="rock" src="http://whiteoakstables.net/chat/audio/rock.wav" preload="auto"></audio>

You may notice that it looks a whole lot like a hyperlink with the src that defines the location of the file. Preload is an optional attribute, it tells your browser to start downloading the file as soon as the DOM, or page elements, have finished loading. In addition to setting preload to true I’ve added an ID attribute so I can reference this particular song in my music player.

The Index File

<!DOCTYPE html>
<html>
 <head>
 <script data-require="jquery@*" data-semver="2.1.3" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
 <link data-require="bootstrap-glyphicons@*" data-semver="3.2.1" rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/img/glyphicons-halflings.png" />
 <link data-require="bootstrap@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
 <script data-require="bootstrap@*" data-semver="3.3.1" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
 <link rel="stylesheet" href="style.css" />
 <script src="script.js"></script>
 </head>
 <body>
 <h1 class="text-center">Bootstrap HTML5 Music Player</h1>
 <audio id="rock" src="http://whiteoakstables.net/chat/audio/rock.wav" preload="auto"></audio>
 <audio id="blues" src="http://whiteoakstables.net/chat/audio/blues.wav" preload="auto"></audio>
 <audio id="electronica" src="http://whiteoakstables.net/chat/audio/electronica.wav" preload="auto"></audio>
 <audio id="classical" src="http://whiteoakstables.net/chat/audio/classical.wav" preload="auto"></audio>
 <audio id="latin" src="http://whiteoakstables.net/chat/audio/latin.wav" preload="auto"></audio>
 <audio id="indie" src="http://whiteoakstables.net/chat/audio/indie.wav" preload="auto"></audio>
 <div class="audiocontroller">
 <i class="audio-logo glyphicon glyphicon-headphones"></i>
 <i class="dynamiclink glyphicon glyphicon-play" id="play"></i></a>
 <i class="dynamiclink glyphicon glyphicon-pause" id="pause"></i>
 <select id="currentTrack">
 <option value="rock">Rock</option>
 <option value="blues">Blues</option>
 <option value="electronica">Electronica</option>
 <option value="classical">Classical</option>
 <option value="latin">Latin</option>
 <option value="indie">Indie</option>
 </select>
 <i class="dynamiclink glyphicon glyphicon-stop" id="stop"></i>
 </div>
 <p class="text-center">
 <a id="author" href="http://design1online.com" target="_blank">by Design1online.com, LLC</a>
 </p>
 </body>
</html>

The Javascript File

//Simple HTML5 Music Player by design1online.com, LLC

var currentTrack = null;
var paused = false;

$(document).ready(function() {
 currentTrack = $('#currentTrack').val();
 
 $("#play").click(function() { play(); });
 $("#stop").click(function() { stop(); });
 $("#pause").click(function() { pause(); });
});

function play() {

 //set the track back to the beginning
 if (!paused) {
 stop();
 currentTrack = $('#currentTrack').val();
 
 //make sure track starts from the begining each time
 document.getElementById(currentTrack).load();
 }

 //play the track
 document.getElementById(currentTrack).play();
}
 
//stop playing the current track
function stop() {
 if (currentTrack) {
 document.getElementById(currentTrack).pause();
 paused = false;
 }
}

//stop the track but don't go back to the beginning
function pause() {
 paused = true;
 document.getElementById(currentTrack).pause();
}

How It All Works

So now let’s talk about the javascript file. At first glance it looks relatively simple because it is! When you want to select a track you simply ask for it using getElementById and then you tell it to play or to pause. One thing that is sadly lacking is a stop() functionality. With html5 you can only pause an audio file — which does stop the playback but it also keeps the audio file at the same position as when you called pause on it. This means that if you wanted to play the audio file from the beginning again and you just called play() it would continue playing from where it left off. That’s where the load() function comes into play — this will tell the audio track to start loading if it wasn’t set to preload and it will reset the track back to the beginning.

The only other thing to mention is the currentTrack variable. I use this to keep track of which of the songs is currently selected and the user wasn’t to listen to.

Angular JS Tutorial: Difference between ng-hide and ng-if

Leave a comment Standard

It took me a while to even realize that there were two different ways toggle the display of HTML DOM elements with Angular JS — thank you Angular docs for not being nearly as helpful as you were when you had comments. Anyways (rant over), this is a really good thing to know because it will help you use the power of Angular to the fullest.

Ng-Show and Ng-Hide

These are use for when you want to toggle the visibility of a DOM element and that toggle can happen any number of times. This is like adding css styles for display. When ng-show is true the css display style is set to block/inline. When ng-show is false the css display style is set to none. Conversely if you use ng-hide instead when ng-hide is set to true display is none and when ng-hide is set to false display is block/inline. The DOM elements are always present no matter if the content is visible or not.

So, now for a good example using ng-show. Let’s say you only want to show a message to someone once they’ve entered their name:

<label for="nameInput">Enter Your Name:</label>
<input type="text" id="nameInput" ng-model="name" />

<div ng-show="name">
  <p>Hello {{name}}, it's nice to meet you!</p>
</div>

This also works using ng-hide, if there’s no name then we don’t want to show our greeting:

<label for="nameInput">Enter Your Name:</label>
<input type="text" id="nameInput" ng-model="name" />

<div ng-hide="!name">
  <p>Hello {{name}}, it's nice to meet you!</p>
</div>

Ng-If

So now let’s harness the power of Angular JS. If you have a DOM element that you ONLY want to display/hide once — like say when the page first or view first loads — then this is the option for you. Ng-If either adds or removes the DOM element from the DOM. When Ng-If is true then DOM element will be added to the document tree. When Ng-If is false the DOM element will be completely removed from the document tree. Why is this a good thing? This means your page will load faster because your document tree doesn’t have to render and then hide DOM elements that you’re never going to use.

Let’s pretend we have a data object like containing the first and last name of some famous people. We want to display this information in a table. However the data in our object comes from a query to a database — so we might not always have results to display. This is where Ng-If is really handy. Take a look at this example where if we have no results in our data object then our table HTML will be completely removed from the DOM — therefor making it faster — before angular renders the view:

<div ng-if="data.length > 0">
  <h4>Famous People</h4>
  <table>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Phone Number</th>
      <th>Email</th>
    </tr>
    <tr ng-repeat="person in data">
      <td>{{person.firstName}}</td>
      <td>{{person.lastName}}</td>
      <td>{{person.phone}}</td>
      <td>{{person.email}}</td>
    </tr>
  </table>
</div>

Node JS Tutorial: How To Create A Simple Server

Leave a comment Standard

This will allow you to quickly setup a working node server in just a few easy steps.

1. Install Node.js

For Windows/Linux
Go to http://nodejs.org and download the
latest version of node for the operating system you want to install it on.

Open node and test if it’s working by typing 2+2 and hitting enter.

For Mac OS X
Visit Homebrew and then open your
command line and run (If you’re prompted to install command line tools go ahead and do that). :

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

When that’s done run you can make sure your install was successful by running:

brew doctor

Then it’s a good idea run this to make sure you have the most up to date copy:

brew update

Then install node by running:

brew install node

Test your install by opening a command line and typing this to see the node version:

node -v

2. Install NPM

This package will help you install lots of node related libraries. You can find out more
about it by visiting https://npmjs.org.
Open a command line and type:

npn install express body-parser

If you get an error on Windows that says something along the lines of

Error: ENOENT, stat...

This means the NPM directory is missing from your filesystem. Navigate to where NPM should be as displayed by the error message and create an empty folder called npm.

3. Create These Simple Server Files

First let’s make our index.html. This should go in the directory you want to serve this index file from. So on a server it would be something along the lines of htdocs/public_html/directory/ or var/www/html and on your local computer it should be whatever directory you did your npm install.

Create the index.html file:

<html ng-app="app">
  <head>
    <title>My First Node Server File</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="css/stylesheet.css">
  </head>
  <body ng-controller="appCtrl">
    <div class="page-header">
      <h1>
        <i class="glyphicon glyphicon-certificate"></i>
        Congratulations!
      </h1>
    </div>
    <section>You have successfully created your first HTML5 node server.</section>
  </body>
  <footer>
    <a href="http://design1online.com" target="_blank">Tutorials by Design1Online.com, LLC</a>
  </footer>
</html>

Now let’s create the server.js file:

'use strict';

// Importing express and body parser libraries
var express = require('express');
var bodyParser = require('body-parser');

//this is a built in node library that handles the file system
var fs = require('fs');


/**
* Server configs
*/

/**
* The port to run your node server on
* 
* If you're running this on a web server this should be 80
* If you're running this locally try 8080 or 9080
*/
var BASE_PORT = 8080;

/** 
* The root directory of your files
*
* By default it uses the current folder this file is in
*/
var ROOT_DIR = __dirname + '/';
ROOT_DIR = fs.realpathSync(ROOT_DIR);
if (!fs.existsSync(ROOT_DIR)) {
	console.log('Error: cannot find working directory: ' + ROOT_DIR);
	exit();
}

/**
* Create an instance of express
*/
var app = express();

/**
 * Adds a simple logging, "mounted" on the root path.
 * Using Express middleware
 **/
app.use(function(req, res, next) {
	console.log('%s %s', req.method, req.url);
	next();
});

/**
 * Allows us to parse http body parameters as json
 **/
app.use(bodyParser.json());

app.use(express.static(ROOT_DIR));

app.listen(BASE_PORT, function() {
	console.log('Node server started @ http://localhost:' + BASE_PORT);
	console.log('Serving static files from ' + ROOT_DIR);
	console.log('Press Ctrl + c for server termination');
});

4. Start the Server

Go to the directory you installed npm in and that your index.html and server.js file reside. This is where you want to start the node server. In the console type:

node server.js

Now open your browser. If you installed node on a server then navigate to your index page on your website. You should see your new node js index file. If you’re running the node server on your local machine then type in http://localhost:BASE_PORT and replace BASE_PORT with the port number you configured in the server.js file. You’ll see your index file in your browser.

Congrats! You’ve successfully create your first node server.

Google Maps Tutorial: You Are Here in 3 Easy Steps

Comments 2 Standard

I’ve been playing with Google maps lately and I thought I would share this little tidbit. It still needs some refinement (ie fetching your location from IP for non-html5 compliant browsers and letting you set your location) but it may give you the start you were looking for.

1. Create a Google maps API key

You can find the instructions on the Google maps Getting Started documentation. Basically you need to generate the key for the website that will be hosting this code so that Google will honor the API request.

2. Create a PHP File

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>You Are Here</title>
    <style>
      html, body {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
            
      #map-canvas {
        float: right;
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
        <script src="javascript.js"></script>
  </head>
  <body>
    <div id="map-canvas" />
  </body>
</html>

3. Create a Javascript File

I called mine javascript.js. If you change the name you’ll need to update it in your .php file above.

/**
* Purpose: ask the browser for the user's location (html5)
* Preconditions: html5 is enabled on the browser
* Postconditions: map initialized with user's position if browser is html5 enabled and position given
**/
function getLocation()
{
    if (navigator.geolocation)
        navigator.geolocation.getCurrentPosition(initMap);
    else
        alert("Geolocation is not supported by this browser.");
}

/**
* Purpose: start the google map
* Preconditions: position object
* Postconditions: map centered around the user's position with a zoom of 15
**/
function initMap(position) {

    console.log('Your position is:', position.coords.latitude, position.coords.longitude);
    
  var mapOptions = {
    zoom: 15,
    center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
  };

  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    var position = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
 
    setMarker(map, position, "You!", "You Are Here");
}

/**
* Purpose: set a marker on a map
* Preconditions: map reference, position, title of the marker window, message in the marker window
* Postconditions: marker event listener added to the map
**/
function setMarker(map, position, title, message) {

     var marker = new google.maps.Marker({
      position: position,
      map: map
    });
        
  marker.setTitle(title);
        
  var infowindow = new google.maps.InfoWindow({
    content: message
  });

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(marker.get('map'), marker);
  });
}

google.maps.event.addDomListener(window, 'load', getLocation);

Demo Working Code

Want to see what it does? Fork this plunker to try it out and see the code. Remember you have to be using a HTML5 compliant browser and give it permission to view your location.