Nikola Brežnjak blog - Tackling software development with a dose of humor
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Home
Daily Thoughts
Ionic
Stack Overflow
Books
About me
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Nikola Brežnjak blog - Tackling software development with a dose of humor
CodeSchool, JavaScript

Codeschool JavaScript Best Practices Notes

I finished the course at CodeSchool, and below are my notes from it.

Level 1

Ternary howto with SIAF

var allPacked = true;
var readyToGo = true;
var adventureTime;

adventureTime = allPacked && readyToGo ?

  function( ){
    return "Adventure time is now!" ;
  }()
  :
  function( ){
    return "Adventuring has been postponed!" ;
  }() ;

console.log(adventureTime);

Short-circuting, if the this.swords is not empty it takes it immediately, without looking at the thing after the ||

this.swords = this.swords || [];

Same goes for &&, as soon as it finds a first falsy value – it returns that. If all falsy, it returns the last one.

Level 2

If you need lengthy, repetitive access to a value nested deep within a JS Object, then cache the necessary value in a local variable.

var numCritters = location.critters.length;
for(var i = 0; i < numCritters; i++){
      list += location.critters[i];
}

//instead of
for(var i = 0; i < location.critters.length; i++){
      list += location.critters[i];
}

//and even better
for(var i = 0, numCritters = location.critters.length; i < numCritters; i++){
    list += location.critters[i];
}

Put script tag just before the ending body tag, or you can also leave them in the head section, but add async keyword. Use a list of variables after the keyword var all at once! Use function join() on the array instead of concatenation. with +=. console.time(“string”) is the opening statement to a timer method that will help us measure how long our code is taking to perform. console.timeEnd(“string”) ends it and prints how long it took. “string” has to be the same in both cases.

var now = new Date();

console.log(+now) == console.log(new Number(now));

 Level 3

 === compares type and content. instanceof – userful to determine, well, the instance of some object 🙂

function Bird(){}
function DatatypeBird(){}
function SyntaxBird(){}
DatatypeBird.prototype = Object.create(Bird.prototype);
SyntaxBird.prototype   = Object.create(Bird.prototype);

Runtime error catching:

try{
   if(someVar === undefined)
        throw new ReferenceError();
}
catch(err){
    if(err instanceof ReferenceError)
        console.log("Ref err:" + err);

    //TypeError
}
finally{
    //this will execute no matter what
}

Avoid eval, with.

Use num.toFixed(2), parseFloat(), parseInt(num, radix). Radix can be from 2 – 36. typeof along with isNan to determine if the number is trully a number.

Level 4

Namespace is an object that groups and protects related data and methods in JavaScript files.

Say you have a code like this:

var treasureChests = 3;
var openChest = function(){
    treasureChests--;
    alert("DA DADADA DAAAAAAA!");
};

you can use namespacing like this:

var DATA = {
	treasureChests : 3,
	openChest : function(){
	    this.treasureChests--;
	    alert("DA DADADA DAAAAAAA!");
	}
};

You then call the function like this: DATA.openChests().

Closures are a feature of JavaScript, used to cause some properties to be private, bound only to a surrounding function’s local scope, and some properties to be public, accessible by all holders of the namespace.

Private properties are created in the local scope of the function expression. Public properties are built within the object which is then returned to become the namespace. Access to private data is thus possible only because of closure within the larger module.

Say you have a code like this:

var CAVESOFCLARITY = {
  stalactites: 4235,
  stalagmites: 3924,
  bats: 345,
  SECRET: {
    treasureChests: 3,
    openChest: function(){
      this.treasureChests--;
      alert("DA DADADA DAAAAAAA!");
    }
  }
};

You would make it into a closure like this:

var CAVESOFCLARITY = function () {

  var treasureChests = 3;

  return {
    stalactites: 4235,
    stalagmites: 3924,
    bats: 345,
    openChest: function () {
        treasureChests--;
        alert("DA DADADA DAAAAAAA!");
    }
  };
}();

If a module references globally-scoped variables, it’s a best practice to bring them into the scope of anonymous closure through the use of a specific technique called global imports.

Say the code is like this and uses a global variable named globalAnswer:

var MySomething = function () {
  var a = 3;

  return {
    getA: function() {return a; },
    summon: function(){
      if(globalAnswer === "42"){
        alert("YEP!");
      }
      else{
          alert("NOPE");
      }
    }
  };
}();

You would rewrite this using global imports like this:

var MySomething = function (answer) {
  var a = 3;

  return {
    getA: function() {return a; },
    summon: function(){
      if(answer === "42"){
        alert("YEP!");
      }
      else{
          alert("NOPE");
      }
    }
  };
}(globalAnswer);

Your import ensures clarity of scope within a module. By using a parameter, you protect the global data that might have been overwritten. All imported data becomes locally scoped to the anonymous function, to be used in closure. Thus, when compared with searching the entire scope, import are both clearer and faster.

Augmentation is the term for adding or changing properties in a module after the module has already been built.

In simple augmentation, the module file and the augmentation file do not share their private state. Augmented module properties may only access the private data from their file’s closure. Private data from the original closure will not be lost, and will be accessible to all original properties that referenced it.

CodeSchool, NodeJS

How to get started with Node.js

Recently I started using CodeSchool to explore new languages/technologies in the web world, and I will post every Tuesday something new that I learn. So far, all I have for them is pure praise, so if you fancy learning something new go check them out. I like them because of one thing in how they do their presentations: first you watch a video in which they explain the concept and then, more importantly (at least in my case), you get the set of challenges where you yourself have to write the code in order to pass on to the next level – awesome! So I would say that their slogan “Learn by doing” is right on the spot.

This is by no means meant as a tutorial, but merely as my notebook where I write down things which I’ve learned. Ok, without further to do, lets check out what’s all this mumbo jumbo buzzword about Node.js.

Node.js (by Ryan Dahl) is in fact a wrapper, written in C, around V8 JavaScript runtime of Google Chrome engine which can be executed on the server.

Blocking vs non-blocking code: Node.js makes non-blocking possible by providing us with a callback function when the process (for example: file reading) is done.

var http = require("http");
var fs = require("fs");

http.createServer(function(request, response){
    response.writeHead(200);
    fs.readFile("file.txt", function(err, contents){
        response.write(contents);
        response.end();
    });
    response.write("This will most likely be printed before the file contents");
}).listen(8080);

To view this, visit http://localhost:8080  in your browser or do a curl request. Interesting thing to note though is that you will not get the same effect if you run it via curl in terminal and in browser, and here is my question on StackOverflow which helps answer why. Long story short (with more info about it later in the post):

…this is simply due to the behavior of the browser rendering engine which cashes the contents until response.end(); arrives, and then renders whole response. Socket.IO and this article should be of help

As explained in the StackOverflow post, I solved this by using Socket.IO (explained in more detail below in the post) and here is the simple example:

//timeoutTest.js
var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

server.listen(8080);

app.use(express.static(__dirname + '/'));

app.get('/', function (req, res) {
   res.sendfile(__dirname + '/timeoutTest.html');
});

io.sockets.on('connection', function (client) {
   client.emit('msg', "This prints right now on connection.");

   setTimeout(function(){
      client.emit('msg', "This prints out after 3 secs.");      
   }, 3000);
});

//timeoutTest.html
<!DOCTYPE html>
<html>
<head>
    <script src="/socket.io/socket.io.js"></script>
    <script src="jquery.js"></script>
    <script>
    $(document).ready(function(){
        var server = io.connect('http://localhost');
        server.on('msg', function(data){
            $('body').append(data + "<br/>");
        });
    });
    </script>
</head>
<body>
</body>
</html>

Upon first execution of the code Node registers events and then it goes into the so called “event loop”.

Instead of response.write(string)  as the last command, you can put it in end() function like this response.end (string);

How to use event emmiters:

var EventEmitter = require('events').EventEmitter;

var logger = new EventEmitter();

logger.on('error', function (msg){
    console.log('error: ' + msg);
});

logger.emit('error', 'sth went wrong');

Same “#$! different packaging:

http.createServer(function(req, resp){}); 

//is the same as:

var server = http.createServer();
server.on("request", function(req, resp){};

Pip | ing:

var fs = require('fs');
var http = require('http');

http.createServer(function(request, response){
    var newFile = fs.createWriteStream('newFile.md');
    request.pipe(newFile);

    request.on('end', function(){
        response.end('uploaded');
    });
}).listen(8080);

//test like this:
curl --upload-file someFile.txt http://localhost:8080

File uploader:

var fs = require('fs');
var http = require('http');

http.createServer(function(request, response) {
	var newFile = fs.createWriteStream("readme_copy.md");
	var fileBytes = request.headers['content-length'];
	var uploadedBytes = 0;

	request.pipe(newFile);

	request.on('data', function(chunk) {
		uploadedBytes += chunk.length;
		var progress = (uploadedBytes / fileBytes) * 100;
		response.write("progress: " + parseInt(progress, 10) + "%\n");
	});

	request.on('end', function(){
        response.end('uploaded');
    });
}).listen(8080);

A side-note; console.log()  does in fact call process.stdout.write.

While calling your own modules, you require them without the “.js”

//custom_hello.js file
var hello = function() {
    console.log("hello!");
}
exports = hello;

//custom_goodbye.js file
exports.goodbye = function(){
    console.log("whot!?");
}

//--usage:
var hello = require('./custom_hello');
var gb = require('./custom_goodbye');

hello();
gb.goodbye();

When you’re requiring with “./” it searches in the current file directory. When, however, you search without it and just write the name of the module it first searches in the file directory for a folder named node_modules, then it goes folder up if it doesn’t find it in recursive.

npm install request  installs it locally and you can (only then!) require it in your code, whilst you should do a global installation  npm install coffee-script -g  if the module has an executable.

//package.json
{
  "name": "My Awesome Node App",
  "version": "1",
  "dependencies": {
    "connect" : "2.2.1",
      "underscore" : "1.3.3"
  }
}

package.json  file is cool as you can distribute the “barebones” app, which once downloaded can be fully installed by doing npm install  (it also installs sub-dependencies if needed).

Express – web application framework for Node.js: npm install express

var express = require('express');

var app = express(); //prior versions: express.createServer();
app.get('/:param', function(request, response){
    var param = request.params.param;
    response.send(param);

    //or, templates are also supported!
    response.render('tweet.ejs', {tweets: tweets, name: username});
});

app.listen(8080);

//tweet.ejs
<h1>Tweets for <%= name %></h1>
<ul>
    <% tweets.forEach(function(tweet)){ %>
        <li><%= tweet.text %></li>
   <% }; %>
</ul>

//but, also you need layout.ejs
<!DOCTYPE html>
<html>
    <head>
        <title>Some cool title</tile>
    </head>
    <body>
        <%- body %>
    </body>
</html>


Socket.IO
 – aims to make realtime apps possible in every browser and mobile device.
npm install socket.io

Simple chat application

var express = require('express'),
	app = express(),
   	server = require('http').createServer(app),
   	io = require('socket.io').listen(server);

server.listen(8080);

app.use(express.static(__dirname + '/'));

app.get('/', function (req, res) {
   	res.sendfile(__dirname + '/chat.html');
});

io.sockets.on('connection', function (client) {
   	client.on('join', function(name){
   		client.set("nickname", name);
   	});

   	client.on("msg", function(data){
      	client.get("nickname", function(err, name){
      		client.broadcast.emit('msg', name + ":" + data);
      	});
   	});
});

Very important thing to note here is that in order to make use of jQuery library you have to set the correct path to your js files in the app.use()  function.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="jquery.js"></script>
    <script>
    $(document).ready(function(){
        var server = io.connect('http://localhost');

        server.on("connect", function(data){
            nickname = prompt("Your nickname:");

            server.emit("join", nickname);
        });

        server.on('msg', function(data){

           $('#recv').append(data + "<br/>");
	    });

	    $("#send").on("click", function(event){
            event.preventDefault();

            $('#recv').append($('#msg').val() + "<br/>");
    	    server.emit('msg', $('#msg').val());
    	});
    });
    </script>
</head>
<body>
    <input type="text" id="msg" name="msg" value="testets"/>
    <input type="submit" id="send" name="send"/>

    <div id="recv" name="recv"></div>
</body>
</html>

mongoDB –  open-source document database, and the leading NoSQL database written in C++. mongojs – A Node.js module for mongodb, that emulates the official mongodb API as much as possible. Installation via npm: npm install mongojs .

//db.js
var databaseURI = "mydb";
var collections = ["users"];
var db = require("mongojs").connect(databaseURI, collections);

module.exports = db;

//dbtest.js
var db = require("./db");

db.users.save({email: "[email protected]", group: "A"}, function(err, saved) {
  if( err || !saved ) console.log("User not saved");
  else console.log("User saved");
});

db.users.find({group: "A"}, function(err, users) {
  if( err || !users) console.log("No A group users found");
  else users.forEach( function(user) {
    console.log(user);
  });
});

In order for this to work mongoDB has to be installed on your system and it has to be running.  Installation instructions are clear and concise on their website, but a tl;dr is: download the zip package, unzip in c:\mongodb , make c:\data\db  folder, run c:\mongodb\bin\mongod.exe.

Recent posts

  • Discipline is also a talent
  • Play for the fun of it
  • The importance of failing
  • A fresh start
  • Perseverance

Categories

  • Android (3)
  • Books (114)
    • Programming (22)
  • CodeProject (35)
  • Daily Thoughts (77)
  • Go (3)
  • iOS (5)
  • JavaScript (127)
    • Angular (4)
    • Angular 2 (3)
    • Ionic (61)
    • Ionic2 (2)
    • Ionic3 (8)
    • MEAN (3)
    • NodeJS (27)
    • Phaser (1)
    • React (1)
    • Three.js (1)
    • Vue.js (2)
  • Leadership (1)
  • Meetups (8)
  • Miscellaneou$ (77)
    • Breaking News (8)
    • CodeSchool (2)
    • Hacker Games (3)
    • Pluralsight (7)
    • Projects (2)
    • Sublime Text (2)
  • PHP (6)
  • Quick tips (40)
  • Servers (8)
    • Heroku (1)
    • Linux (3)
  • Stack Overflow (81)
  • Unity3D (9)
  • Windows (8)
    • C# (2)
    • WPF (3)
  • Wordpress (2)

"There's no short-term solution for a long-term result." ~ Greg Plitt

"Everything around you that you call life was made up by people that were no smarter than you." ~ S. Jobs

"Hard work beats talent when talent doesn't work hard." ~ Tim Notke

© since 2016 - Nikola Brežnjak