Dev Tools Revisited, Plus Candy

Posted on

Remember that post that mentioned dev tools? Yeah, let’s revisit that. We already know a search for “web developer tools” out there on The Googles returns something akin to candy store. And I’m the kid. The kid who wants all the Swedish Fish, all the Willy Wonka stuff, and all the peanut butter M&Ms. Throw it all in a bag, and you get a bag of regret. Do the same downloading all the tools out there, and you get an environment of regret. So, why not pick out all the candy that compliment each other…

Sublime Text 3 – http://www.sublimetext.com/3
A super fancy, super easy to work with, text editor.

Terminal
Good ‘ol basic terminal. I’m using this to run node and mongoDB locally.

GitHub – https://github.com/
Cuz, duh.

CodeKit – https://incident57.com/codekit/
Basically your tech lead at work. I’m using this to bring in my non-node dependencies (which it does through bower-powering your project), error checking, and launching my app).The best part: pre-loaded meme icons for your imported projects.

skitch

This project so far definitely gets the “facepalming Picard” stamp of approval. Also some cloud tools have been setup as well to ease the pain of making the code available in all the places:

Cloud9 IDE – https://c9.io/
The features – they’re so rich. The place my projects go when they want to run free of your local machine. You can even run node apps!

MongoLab – https://mongolab.com/
It’s like local mongoDB, but in the cloud.

Doin’ the MEAN thing:

  • MongoDB/Mongoose
  • ExpressJS
  • AngularJS
  • Node.js

Toss in Bootstrap 3 for some fancy UI stuff. Time to take a time machine to the future..

HT1427_System-Preference_004-en

Not that time machine.

d0ef_back_to_the_future_mark1_delorian

Yeah – that’ll do. Tools that are planned on being utilized in the near future:

Yeoman – http://yeoman.io/
The scaffolding tool/fancy, polite gentleman who was mentioned in the last post.

Phaser – http://phaser.io/
HTHML5 game framework that’ll probably be awesome to work with.

..There wasn’t really any candy in this post.

Fork the Couch (Messin’ with the Couch – Part 2)

Posted on Updated on

At some point in our lives, things change. One week you’re asked to focus on task A, and the next you’re asked to drop task A in favor of B. One day you’re using CouchDB, and then  you drop the Couch (on your foot, nonetheless) in favor of MongoDB. Same rules apply. Why?

picard-facepalm2

‘Nuff said. Let’s shift the gears to another NoSQL beast: MongoDB. MongoDB, meet node.js, AngularJS, and Express – the tools we want to incorporate the build out the foundations of our site. Oh, you’ve all met before? The MEAN stack you say? Well, that just made our lives a heck of a lot easier. Another awkward introduction avoided.

Now that we’re acquainted with this framework “click”, what are we working with here now?

  • AngularJS – our frontend buddy
  • node.js – the base install to talk with our party on the backend
  • express – a node.js framework ( node module)
  • mongoose – another node module that’ll be our liaison to the mongo db
  • mongoDB – similar to our dropped couch. Go along with it.

A skip, jump, a hob over to MongoDB’s site and documentation gives you everything you need to get started. Once the install is complete, and your mongo server has initiated, creating a new database to hold our score information is as easy as “use scores”. Literally. A little “show dbs” within mongo gives us something like the following:

5_24_3

Nice. Let’s throw some data into it! With node.js installed an at the ready, time to create a test site to emulate our leaderboard and saving scoring information. A wildly helpful tool to set up the scaffolding for our site: Yeoman.

Yeoman_-_Modern_workflows_for_modern_webappsHe’s ready, willing, and supremely fancy. Fancy enough to provide generators (there’s a mongoose one out there for our needs in the future), Bower for our dependencies, and Grunt for builds and testing. Awesome stuff that’s a little beyond the scope of what we’re trying at this very moment (the mongoose yeoman generator would give us a ton of material we don’t need yet), but should be in our back pocket for the future.

For now, we mooch. Mooch off tutorials. Like this one over at Scotch.io (they have tons of great articles and sample code). No shame – we are learning after all. A git of the provided code, and a little name tweaking to fit our needs, give us some simplistic scaffolding to mess with:

5_24_5

  • app –> models –> score.js – the mongoose model definition for our score document object (playername: string, scorevalu: number)
  • app –> routes.js – express bits for the API calls
  • config –> database.js – defines where our mongoDB lives
  • node_models – all the node stuff we need (local install with npm)
  • package.json – defines our dependencies and app information
  • public –> core.js – the Angular bit for our app module and main controller to drive the app
  • public –> index.html – the landing page that’ll bring in the Angular bits
  • server.js – the setup for express and mongoose

It’s kind of a lot to take in, but the tutorial is one that we can get a long with. Some key things that gotta change:

  1. Database definition in database.js – “Have it your way” (make it point to your instance)
  2. Update the model in score.js for the score info – we need a playername string and a scorevalue number
  3. The index.html landing page receives a complete overhaul. We want tables – always tables.

A little this, and a little that, and the project looks something like this when it’s changed for our needs. With our wavering confidence, we can test out the APIs that were messed with by handing them off to the Postman. APIs signed, sealed, delivered? Good. Let’s see this app at work.

MongoDB running? Check.

Confirm we have a “scores” database living in there? Check.

Start our node app and have it listen in on our specified port (with a simple “node server.js” on the command line? Check.

Localhost it up on that port and what do we get? Aww yissss…

5_24_6

 

My goodness. Look at that. Can we get a playername and score up in here?

5_24_7

Yes, yes we can. If we look over at the terminal we ran our “node server.js” command on, we’ll see some epic API calls going on reflecting the activity on the site

5_24_8

 

And the “scores” database. What about that?

5_24_9

Yep, data’s all there. Sweet! The foundation for the leaderboard functionality of the site is complete. There’s still a lot more to take care of, namely around data validation, sorting scores, and creating a view just for the leaderboard, but this is an awesome start. Next time – get your sort on!

Messin’ with the Couch – Part 1

Posted on Updated on

Awesome. We’ve got a bit of data crumbs on our Couch, now let’s see if you can interact with our Couch from a basic webpage. That’s the ultimate goal, right? But which tools will we use? The web is swarming with frameworks, modules, plugins, and templates to help a developer create a web work-of-art. This can be mildly overwhelming for the newbie web/mobile developer, so let’s try and narrow down the plethora of tools out there that we can use to build out the pieces we may need.

The tool bag

No, not the guy that went to your high school who tried way too hard to be cool. This is the pack of tools that will help us lay down our back-end, midtier, and UI. To get us started (and mind you, this is always subject to change), let’s jot down the technologies we may want to incorporate to help us meet the goal of this app, and what we’re going to use them for.

  • CouchDB – our database, duh!
  • node.js – Our poison of choice to talk to our database. With it comes a bunch of modules that can be installed separately to help make our lives a little easier.
  • AngularJS – Google’s behemoth of a framework that will force us into the MVC architectural pattern. We’ll start out MVW (model-view-whatever) and try and make our way to MVC.
  • Bootstrap – a gem of a front-end framework that is comprised of a bunch of HTML and CSS goodies. It’ll help us make a sweet-looking site that’ll be just as responsive we when migrate over to a mobile application.

Take a REST

We have our database sitting pretty on our Couch, now let’s REST on it. Let’s start simple and use basic AJAX calls via jQuery to do stuff with it. We’ll be using this straightforward Couchdb tutorial as a flotation device to start development until we’re comfortable enough to swim the waters alone. We’ll add a little flair with Bootstrap to make ourselves feel better.

First, lets look at our database. It’s been oversimplified to make things less intense in the beginning. We’ve added three sample documents as test data in our Pterobase

5-17-2014 5-18-37 PM

Each document has an _id and _rev (CouchDB-assigned), a playername, and a scorevalue

5-17-2014 5-26-56 PM

Now, over to our text editor. To get started, we’ll cram everything into a single index.html file. Cringe-worthy, yes. But, we need to start somewhere. Running in Visual Studio (for the PC folks) will make things a bit easier when it comes to running things on a web server.

The body


<body onload="createView(); getScores();">
<div class="alert alert-success" style="display: none">Relax. We got ya connected, bro.</div>
<div class="alert alert-danger" style="display: none">Aw snap, son. Didn't connect.</div>
<h1>Pterrible Scores</h1>
<input type="button" id="add" value="Add" onclick="addScore();" />
<div id="scores"></div>
</body>

view raw

index.html

hosted with ❤ by GitHub

Ah, the body of a webpage. And a Bootstrapin’ body at that! Our onload functions are going to create a view on our CouchDB (more on that later) and will get our scores from the database. We’ll throw in some spicy alerts a-la Bootstrap to let us know if our connection to our pterobase failed, an add button too add a new player name and score (for giggles), and a table to display our data

The view (not the television show)


function createView() {
var view = {
"language": "javascript",
"views": {
"playername_w_score": {
"map": "function(doc) {if (doc.scorevalue) {emit(doc.scorevalue, doc);}}"
}
}
}
$.ajax({
type: "PUT",
url: DATABASE + "/_design/scores",
contentType: "application/json",
data: JSON.stringify(view)
});
}

This nugget will create a view within our pterobase. CouchDB uses these views to spit out the information we want to see, given what we want to do. In this case, we want a view of an entire document, but only if that document has a scorevalue and a playername field. We also want the score as the key and the value to be the entire document (hence the “emit(doc.scorevalue, doc);”). Why? No particular reasoning, it’ll just be easier for us to work with. We could certainly make doc._id our actual key, but nah. We can test this out in Futon’s temporary view tool

5-17-2014 6-11-21 PM

 

Every document in our pterobase has these two fields at the moment, so when we run our function, all of our documents are returned. Success!

The services


function getScores() {
$.ajax({
url: DATABASE + "/_design/scores/_view/playername_w_score",
success: function (data) {
var view = JSON.parse(data);
var scores = [];
$(".alert-success").show();
$(view.rows).each(function (index, item) {
scores.push(item.value);
});
displayScores(scores);
},
error: function () { $(".alert-danger").show(); }
});
}
function displayScores(scores) {
var html = "<table class=\"table .table-hover>\"";
$(scores).each(function (index, score) {
var edit = "<input type='button' value='Edit Name' " +
"onclick='editPlayerName(" + JSON.stringify(score) + ")' />";
var del = "<input type='button' value='Delete' " +
"onclick='deleteScore(" + JSON.stringify(score) + ")' />";
html += "<tr>";
html += "<td>" + score.scorevalue + "</td>";
html += "<td>" + score.playername + "</td>"
html += "<td>" + edit + "</td>";
html += "<td>" + del + "</td>";
html += "</tr>";
});
html += "</table>";
$('#scores').empty();
$('#scores').append(html);
}
function addScore() {
var scorevalue = prompt("Enter a score");
var playername = prompt("Enter a name");
if (scorevalue && playername) {
var score = {
"scorevalue": scorevalue,
"playername" : playername
};
$.ajax({
type: "POST",
url: DATABASE,
contentType: "application/json",
data: JSON.stringify(score),
success: function () {
getScores();
}
});
}
}
function editPlayerName(score) {
var newplayername = prompt("New name", score.playername);
if (newplayername) {
score.playername = newplayername;
$.ajax({
type: "PUT",
url: DATABASE + "/" + score._id,
contentType: "application/json",
data: JSON.stringify(score),
success: function () {
getScores();
}
});
}
}
function deleteScore(score) {
var doit = confirm("Do you really want to delete this score '" +
score.scorevalue + "'?");
if (doit) {
$.ajax({
type: "DELETE",
url: DATABASE + "/" + score._id + "?rev=" + score._rev,
success: function () {
getScores();
}
});
}
}

view raw

do stuff

hosted with ❤ by GitHub

The fun part! Time to interact with our data. First we’ll specify and attempt to connect to our database. The object returned will be exactly what we saw in our temporary view. We’ll be getting back score objects and storing them to an array for easy finangling in our displayScores function. Our addScore() and editPlayerName() functions are a formality, we’re not going to allow this type of misconduct in our schools! I mean our application. Our deleteScore() function is something we might want to consider keeping.

Combine all the things!

What’s this look like smashed together in our single index.html?


<!DOCTYPE html>
<html>
<head>
<title>Scores</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script&gt;
<script type="text/javascript">
var DATABASE = "http://localhost:5984/pteroscores&quot;;
function getScores() {
$.ajax({
url: DATABASE + "/_design/scores/_view/playername_w_score",
success: function (data) {
var view = JSON.parse(data);
var scores = [];
$(".alert-success").show();
$(view.rows).each(function (index, item) {
scores.push(item.value);
});
displayScores(scores);
},
error: function () { $(".alert-danger").show(); }
});
}
function displayScores(scores) {
var html = "<table class=\"table .table-hover>\"";
$(scores).each(function (index, score) {
var edit = "<input type='button' value='Edit Name' " +
"onclick='editPlayerName(" + JSON.stringify(score) + ")' />";
var del = "<input type='button' value='Delete' " +
"onclick='deleteScore(" + JSON.stringify(score) + ")' />";
html += "<tr>";
html += "<td>" + score.scorevalue + "</td>";
html += "<td>" + score.playername + "</td>"
html += "<td>" + edit + "</td>";
html += "<td>" + del + "</td>";
html += "</tr>";
});
html += "</table>";
$('#scores').empty();
$('#scores').append(html);
}
function addScore() {
var scorevalue = prompt("Enter a score");
var playername = prompt("Enter a name");
if (scorevalue && playername) {
var score = {
"scorevalue": scorevalue,
"playername" : playername
};
$.ajax({
type: "POST",
url: DATABASE,
contentType: "application/json",
data: JSON.stringify(score),
success: function () {
getScores();
}
});
}
}
function editPlayerName(score) {
var newplayername = prompt("New name", score.playername);
if (newplayername) {
score.playername = newplayername;
$.ajax({
type: "PUT",
url: DATABASE + "/" + score._id,
contentType: "application/json",
data: JSON.stringify(score),
success: function () {
getScores();
}
});
}
}
function deleteScore(score) {
var doit = confirm("Do you really want to delete this score '" +
score.scorevalue + "'?");
if (doit) {
$.ajax({
type: "DELETE",
url: DATABASE + "/" + score._id + "?rev=" + score._rev,
success: function () {
getScores();
}
});
}
}
function createView() {
var view = {
"language": "javascript",
"views": {
"playername_w_score": {
"map": "function(doc) {if (doc.scorevalue && doc.playername) {emit(doc.scorevalue, doc);}}"
}
}
}
$.ajax({
type: "PUT",
url: DATABASE + "/_design/scores",
contentType: "application/json",
data: JSON.stringify(view)
});
}
</script>
</head>
<body onload="createView(); getScores();">
<div class="alert alert-success" style="display: none">Relax. We got ya connected, bro.</div>
<div class="alert alert-danger" style="display: none">Aw snap, son. Didn't connect.</div>
<h1>Pterrible Scores</h1>
<input type="button" id="add" value="Add" onclick="addScore();" />
<div id="scores"></div>
</body>
</html>

view raw

smashin

hosted with ❤ by GitHub

Nice! Let’s launch our app. First let’s bomb it with bogus connection information to see the worst-case scenario
5-17-2014 6-31-36 PM

Now that’s a bad day. Alright, let’s be serious here

5-17-2014 6-33-40 PM

 

Now that’s progress. Let’s make a moment to reflect on our success. Pffft, naw – time to press all the buttons! Let’s add a new score since it’s what we’re ultimately striving for, as our application will need to commit a new score and the player’s name to our database. In the logic for our addScore function, we prompt the user to provide a score (this will obviously be handled systematically once we create our game) and a playername. If our app doesn’t get this information, it won’t attempt to POST to our database.

5-17-2014 6-34-33 PM

Naturally. And a name…

5-17-2014 6-34-48 PM

 

Ok, let’s see some updates. Our page after providing the information we wanted…

5-17-2014 6-34-56 PM

Behaviour as desired! This means our database updated too, right? Let’s walk to the Couch. It looks like our site made our design (with our design function inside)

5-17-2014 6-43-36 PM

And our new score was added..

5-17-2014 6-46-18 PM

POST functionality is officially a-go. The other functions we threw in work like a gem as well (give a little trust here).

Whew, that’s a lot to take in. Let’s let that sink in for a bit. Part 2 of Messin’ with the Couch will begin our epic journey into node.js and AngularJS territory. And research shows, it’s gonna be a crazy, yet rewarding, trip.

 

 

Apache Says “Relax”

Posted on Updated on

To me, databases are that big elephant in the room that no one wants to deal with.  They’re that essential, vital thing you have to have, but you try and convince yourself that maybe, just maybe,  you can “work around it” and delve right into the cool stuff. Do you really have to deal with this database stuff?

Yeah, yeah ya do. Face the elephant. The good news is, for this project, it’s a tiny elephant – we got this. We’ll candy-coat that tiny elephant and make it a NoSQL database. For “Pterrible Pterodacyl”, we’re going to use CouchDB. Why? Well, it’s NoSQL, append-to (because we totally don’t need to update), and well, why not. Just relax. It’s CouchDB.

Relaxed? Good. CouchDB’s plushy Futon web interface makes it quick and easy to start making our database. But first, we need to have a plan in place. What are we trying to accomplish here with our database? How can we make it scalable so we can  add fancy new features later one quickly and efficiently? What do we want to keep track of? What’s our ultimate goal?

Why do we want our database?

We want to display a high score leaderboard with a user’s name and their score.

What info will we know when a user commits score to the leaderboard?

  • The name of our game (we want to record this info in case we want to make more games that utilize this database)
  • Datetime when the player starts the game round (press start)
  • Datetime when the player ends the game round (game over)
  • The time from start to end of round
  • Their score for that round
  • The name of the player

What the heck does that look like in Db schema land?

Looks like we’ve got a few objects here. We’ve got the game, the player, and the player’s round information. We want to slap all that information into one centralized table where the pieces can come together, looking something like this:

5-14-2014 3-32-54 PM

A single player can have many player games. A single game can have many player games. And, for now, a player game will consist of one, and only one, round.

What the heck does this look like on the “Couch”?

Let’s make our way back to the Futon, now that we know what we’re dealing with. Let’s create a database – got it, there’s a button for that. We’ll call ours “pterobase”. Then let’s make a new tab– oh what the heck is this?

5-14-2014 3-58-25 PM
OK, new document?

5-14-2014 4-01-36 PM
What? Stop. Just stop. Let’s do a little research. So this is a document-driven, no-rules, punk of a “database”. Punk is cool. Rock isn’t dead. Let’s do this for real and look at our picture again. It’s not completely useless. We can derive “types” of documents from our tables. But the fact that we don’t have to adhere to a schema puts a little less pressure on us to get things right the first time. For now we only want to commit data to our database if the user decides to save their score.

The leaderboard round (lround) type document

This document will only be created when the player decides to “save to leaderboard”. Otherwise, we ain’t saving their info and their play information is dead to us (kind of – we’ll want to keep track of high score per session. You’ll see. We’re also doing this to cut down on size). So, what will we care about in this document?

  • player name
  • score
  • datetime of round start
  • datetime of round end
  • total round play time

Do we really need to know much else? Nah. Not at the moment anyways. We’re trying to relax, remember? So, here’s what this looks like on the Couch:

5-14-2014 5-08-39 PM

And its source:

{
   "_id": "0e38ee771833be7f695c0fe660001407",
   "_rev": "2-2a287df6ce771b03f4d6ae4724811064",
   "type": "lround",
   "player_name": "King Kazma",
   "lround_start": "2014-05-14'T'16:05:00",
   "lround_end": "2014-05-14'T'16:06:30",
   "lround_play_time": "0:00:01:30",
   "lround_score": 4
}

That’s it! That’s it? Not exactly. We’ll need to get acclimated with actually doing stuff with the data in our document. That’s next time.

 

The Plannoning

Posted on

Bad “The Reckoning” reference there, but whatever. With any project, we need to define the goal for what we’ll be working on and what we’re trying to accomplish. We’ll start with the big picture, then work our way down to the nitty-gritty details.

The big picture

To create a helicopter game. You know, the one you’d play for the entire duration of any grade-school class held in a PC lab: http://www.addictinggames.com/action-games/helicoptergame.jsp

It’s going to be called “Pterrible Pterodactyl”, because that’s how I roll. We’re going to start with a full web site, then work our way smaller to a mobile site, followed by perhaps an Android application (since I lack the tools for iOS development). Pterrible Pterodactyl will have user accounts and a leader board so we can have justifiable bragging rights.

The functionality

What’s the criteria for each piece of the Pterrible Pterodactyl puzzle?

The database

  • needs to hold user info – user name, password, first name
  • needs to hold scoring info – score, time, datetime of when score was recorded… all tied to a particular user*

User creation/login

  • user can create a username (can already exist)
  • user can create alphanumeric password that’s greater than 5 characters
  • existing user can login with username and password
  • user can play as guest, but their score won’t be recorded

The site

  • user can login
  • user can create user
  • user can access their user page
  • user can play game

The game

  • user can start game
  • user can view how to play
  • user can view credits
  • user can hold the spacebar to go higher
  • user can release spacebar to go lower
  • game’s over when user hits obstacle (wall, block, moving block)
  • pterodactyl speed increases over time
  • score saves if user is logged in upon game over

The tools

We’re going to need stuff to make this work. Lots of stuff. Let’s make a list and take it one step at a time.

  1. A database – we have to store the user and score information somewhere. NoSQL will certainly be preference, because THE FUTURE.
  2. A fancy DOM manipulation/data handling framework – this site ain’t gonna change itself. We’ll need to research what’ll be best for what we are trying to accomplish. I’m a sucker for JQuery, however AngularJS may be the viable option with its data-mining capabilities and growing popularity.
  3. A text editor – because duh.
  4. Graphic design tools – our site needs a UI and the game will certainly need sweet graphics. Adobe Illustrator and Photoshop will probably be our best friends during the design phase.
  5. A code repository – let’s contribute to the cause. GitHub will be the obvious choice.
  6. A host – the site will eventually have to live out there somewhere. This will also give a huge lesson in packaging up and deploying all the pieces that’ll make our site out to a server.

I’m sure more will come up as the project progresses, but it’s a start. Next step – let’s get a database! We know what information we’ll want to store from the beginning, and it’ll be the groundwork for our application. Our homework is to do a bit of research to find an awesome, free, database that will suit our needs. Also the less (or no) SQL, the better.