TypeScript: An hour with TypeScript

Over the past few day we’ve been evaluating using Angular 1.x vs. Angular 2 for a new project on which in the past we would have used Angular 1.x without much debate. However, with release of Angular 2 around the corner we decided to evaluate what starting a project with Angular 2 would involve. As we started digging in it became clear that using Angular 2 without programming in TypeScript would be technically possible but painful to put it lightly. Because of the tight timeline of the project we decided that was too large of a technical risk so we decided to move forward with 1.x. But I decided to spend some time looking at TypeScript anyway, for science. I didn’t have anything substantial to write but needed to hammer out a quick HTML scraper so I decided to whip it up in TypeScript.

Getting started with TypeScript is easy you just use npm to install the tranpiler and you’re off to the races. As I started experimenting, I fired up PhpStorm 10+ and was thrilled to learn it has good TypeScript support out of the box (thanks JetBrains!). The scraper I was writing is pretty simple - make a series of HTTP requests, extract some elements out of the HTML via CSS selectors, and write the results out to a CSV. Coming from a JavaScript background, jumping right into TypeScript was easy enough since TypeScripts’ syntax is basically ES2015 with additional Java or C# like type declarations. The scraper is less than 100 lines so I didn’t get a great sense of what programming with TypeScript would be like but here are some initial takeaways.

It’s easy to end up missing out on the benefits. Since TypeScript is a superset of JavaScript you’re free to ignore all the type features and write TypeScript that is basically ES2015. Combine that with the fact that the tsc transpiler will produce JavaScript even with type errors and you can quickly find yourself not enjoying any of the benefits TypeScripts introduces. This issue isn’t unique to TypeScript since you can famously write You Can Write FORTRAN in any Language but I think since its a superset of an existing, popular langue the temptation is much stronger.

Discovering functionality in modules is easier. In order to properly interface with nodejs modules you’ll need to grab type definitions from somewhere like DefinitelyTyped. The definition files are similar to “.h” files from C++, code stubs that just provide function type signatures to TypeScript. An awesome benefit of this is that it’s much easier to “discover” the functionality of nodejs modules by looking at how the functions transform data between types. It also makes it much easier to figure out the parameters of a callback without having to dig into docs or code.

Typed generics will unequivocally reduce bugs. I’d bet a beer or two that most web developers spend the majority of their day writing code that deals with lists. Creating them, filtering them, transforming them, etc. Unfortunately, most of the popular scripting languages don’t have support for typed generics and specifically enforcing uniform types within arrays. Specifically with JavaScript, it’s pretty easy to end up at a point where you’re unsure of what’s contained in a list and moreover if the objects within it share any of the same properties. Because of this, I think TypeScript’s typed generics will cut down on bugs almost immediately.

TypeScript is definitely interesting and it’s tight coupling to Angular 2 only bolsters how useful it’ll be in the future. Next up, I’d be interested in building something more substantial with both a client and server component and hopefully share some of the same code on both.

As always, questions and comments are more than welcome!

React Native: Loading onto iOS devices

After testing our React Native app on the simulator for a day or two we, similar to a young Kobe Bryant, decided to forgo college and take our talents to the big leagues, by testing our native app on an actual device.

This is a good practice because from a hardware standpoint you’re phone is a very different device than your Mac. Because of the more powerful CPU in your computer there is always the chance that applications that run seamlessly on the Computer’s simulator run choppy on an actual device.

For our purposes we wanted to ensure that our react Native components looked and felt native on a device, and that the positive results produced on the simulator were not just a fluke.

The Nitty Gritty

In our experience the process of getting an App on an actual device is somewhat painful. To help you avoid the same pitfalls that caused us headaches we wanted to give you some solutions to the most common problems you will run into while trying to get your app on your device.

  1. Setting up your iOS developer account: First and foremost it is import to correctly configure your iOS developer account so that you can run your application on an iOS device. This step is easily the most painful part of the process because of how much outdated information that exists on this subject. After poking around for a bit this was the most helpful tutorial that we could find - How to Deploy your App on an iPhone
  2. Plugin your device and ensure that your Xcode and iOS versions are compatible: Right after your developer account is setup the next step is to check and make sure that you are running compatible versions of Xcode and iOS. If not then you will be given an error saying, “The Developer Disk Image could not be mounted”. The simplest fix for this issue is to always make sure that you are running the most recent versions of Xcode and iOS. However, if for some reason you do not want to update your version of Xcode another fix would be to set the deployment target of your application to a version equal to or behind the current version of iOS running on your phone.
  3. Accessing the development server from the device: Now that your app is installed on your device feel free to open it up and navigate through it’s screen. However, if the app needs to make calls to a server running locally on your computer then you are going to have to connect your app to that server. The fastest way to do this is to update the AppDelegate.m file and change the IP in the URL form localhost to your laptop’s IP address. For more information on this step checkout the react documentation at - Running On Device - React Native

NodeJS: Running code in parallel with child_process

One of the nice things about nodejs is that since the majority of its libraries are asynchronous it boasts strong support for concurrently performing IO heavy workloads. Even though node is single threaded the event loop is able to concurrently progress separate operations because of the asynchronous style of its libraries. A canonical example would something like fetching 10 web pages and extracting all the links from the fetched HTML. This fits into node’s computational model nicely since the most time consuming part of an HTTP request is waiting around for the network during which node can use the CPU for something else. For the sake of discussion, let’s consider this sample implementation:

var request = require("request");
var Q = require("q");
var cheerio = require('cheerio');

require('request').debug = true

function makeRequest(url){
    var df = Q.defer();
        
    request(url, function (error, response, body) {
       var $ = cheerio.load(body);
       var links = [];
       
       $("a").each(function(){ 
           links.push( $(this).attr("href") );
       });       
              
       df.resolve(links);
    });
    
    
    return df.promise;    
}

var targetUrls = ["http://www.cnn.com", "http://www.setfive.com", "http://gawker.com/"];
targetUrls = targetUrls.map(makeRequest);

Q.all(targetUrls).then(function(results){
   process.exit(0);
});

Request debugging is enabled so you’ll see that node starts fetching all the URLs at the same time and then the various events fire at different times for each URL:

REQUEST { uri: 'http://www.cnn.com', callback: [Function] }
REQUEST { uri: 'http://www.setfive.com', callback: [Function] }
REQUEST { uri: 'http://gawker.com/', callback: [Function] }
REQUEST make request http://www.cnn.com/
REQUEST make request http://www.setfive.com/
REQUEST make request http://gawker.com/
REQUEST onRequestResponse http://www.cnn.com/ 200 { 'x-servedbyhost': 'prd-10-60-165-19.nodes.56m.dmtio.net'}
REQUEST reading response's body
REQUEST finish init function http://www.cnn.com/
REQUEST onRequestResponse http://gawker.com/ 200 { 'cache-control': 'stale-if-error=86400, stale-while-revalidate=300',}
REQUEST reading response's body
REQUEST finish init function http://gawker.com/
REQUEST response end http://www.cnn.com/ 200 { 'x-servedbyhost': 'prd-10-60-165-19.nodes.56m.dmtio.net', }
REQUEST end event http://www.cnn.com/
REQUEST has body http://www.cnn.com/ 103558
REQUEST emitting complete http://www.cnn.com/
REQUEST response end http://gawker.com/ 200 { 'cache-control': 'stale-if-error=86400, stale-while-revalidate=300',}
REQUEST end event http://gawker.com/
REQUEST has body http://gawker.com/ 373120
REQUEST emitting complete http://gawker.com/
REQUEST onRequestResponse http://www.setfive.com/ 200 { server: 'nginx',}
REQUEST reading response's body
REQUEST finish init function http://www.setfive.com/
REQUEST response end http://www.setfive.com/ 200 { server: 'nginx',
REQUEST end event http://www.setfive.com/
REQUEST has body http://www.setfive.com/ 13611
REQUEST emitting complete http://www.setfive.com/

So we’ve demonstrated that node will concurrently “do” several things at the same time but what happens if computationally intensive code is tying up the event loop? As a concrete example, imagine doing something like compressing the results of the HTTP request. For our purposes we’ll just throw in a while(1) so it’s easier to see what’s going on:

var request = require("request");
var Q = require("q");
var cheerio = require('cheerio');

require('request').debug = true

function makeRequest(url){
    var df = Q.defer();
            
    request(url, function (error, response, body) {
       var $ = cheerio.load(body);
       var links = [];
    
       var startedAt = Math.floor(new Date() / 1000);    
       while( Math.floor(new Date() / 1000) - startedAt < 5 ){
            true;
       }
       
       $("a").each(function(){ 
           links.push( $(this).attr("href") );
       });       
              
       df.resolve(links);
    });
    
    
    return df.promise;    
}

var targetUrls = ["http://www.cnn.com", "http://www.setfive.com", "http://gawker.com/"];
targetUrls = targetUrls.map(makeRequest);

Q.all(targetUrls).then(function(results){
   process.exit(0);
});

If you run the script you’ll notice it takes much longer to finish since we’ve now introduced a while() loop that causes each URL to take at least 5 seconds to be processed:

# Without the 5 second penalty
ashish@ashish:~/workspace/$ time nodejs urltest.js 

real	0m0.694s
user	0m0.657s
sys	0m0.040s

# With the 5 second penalty
ashish@ashish:~/workspace/$ time nodejs urltest.js 

real	0m14.976s
user	0m14.915s
sys	0m0.076s

And now back to the original problem, how can we fetch the URLs in parallel so that our script completes in around 5 seconds? It turns out it’s possible to do this with node with the child_process module. Child_process basically lets you fire up a second nodejs instance and use IPC to pass messages between the parent and it’s child. We’ll need to move a couple of things around to get this to work and the implementation ends up looking like:

var request = require("request");
var Q = require("q");
var cheerio = require('cheerio');
var childProcess = require('child_process');

function makeRequest(url){
    var df = Q.defer();
            
    request(url, function (error, response, body) {
       var $ = cheerio.load(body);
       var links = [];           
       var startedAt = Math.floor(new Date() / 1000);
       while( Math.floor(new Date() / 1000) - startedAt < 5 ){
            true;
       }    
       
       $("a").each(function(){ 
           links.push( $(this).attr("href") );
       });       
              
       df.resolve(links);
    });
        
    return df.promise;    
}

var targetUrls = ["http://www.cnn.com", "http://www.setfive.com", "http://gawker.com/"];
var numRecieved = 0;

function recieveLinks(links){
    console.log(links); 
         
    numRecieved += 1;
    if(numRecieved == targetUrls.length){
        process.exit(0);
    }
}

/** 
 * We'll detect that we're in the "master" 
 * by passing an argument when running
 */
if( process.argv.length == 3 ){
    
    for(var i = 0; i < targetUrls.length; i++){
       var cp = childProcess.fork(__filename);
       cp.on("message", recieveLinks);
       cp.send( targetUrls[i] );
    }
        
}else{
    process.on('message', function(url) {
        
        makeRequest(url).then(function(links){
            process.send(links);
        });
        
    });
}

What’s happening now is that we’re launching a child process for each URL we want to process, passing a message with the target URL, and then passing the links back to the parent. And then running along with a timer results in:

ashish@ashish:~/workspace/$ time nodejs urltest.js master
real	0m5.878s
user	0m0.355s
sys	0m0.040s

It isn’t exactly 5 seconds since there’s a non-trivial amount of time required to start each of the child processes but it’s around what you’d expect. So there you have it, we’ve successfully demonstrated how you can achieve parallelism with nodejs.

React Native: 48 hrs with React

Here at Setfive, when not helping our clients with their technology woes, we love experimenting with fun new technology and continuously growing our professional tool kit. As of late we have been throwing around some potential ideas for a Setfive iPhone app (get Chicken Pad Thai delivered no matter where you are in the world) and have been looking at a couple of tools to turn this lofty dream into a reality.

Since no one in the office has any significant experience with Objective C or Swift we decided that, rather than bang our heads against the wall trying to learn the nuances of yet another programming language, we would look to one that we already know, and decided to dip our toes into the JavaScript driven React Native ecosystem.

In the past we have taken our chances with other cross-platform native apps (PhoneGap in particular) that allow you to wrap a web app into a web view however, these methods fall short; if the looks of your app don’t bother you then the serious performance hit that comes from interfacing directly with native objects will.

If you are unfamiliar with React Native, it’s an open source JavaScript framework, built by Facebook, that allows the production of iOS and Android applications using a syntax familiar to HTML. What separates React from other frameworks is that it runs a separate JavaScript thread to control the UI of your application so it can utilize native mobile components. The idea is that this should lead to a seamless user experience that feels both polished and native. After some hands on experience we can say that React did not disappoint.

What we built

In order to test React a little bit farther than the simple hello world example we decided to build a simple application on top of our preexisting Rotorobot API. This app allows users to see the available players for a daily fantasy sports contest on that night.

To get started, we needed an index page that would show up when the app was loaded. Just to keep things simple we incorporated a minimalist layout with a UIButton that responds when pressed.

Upon pressing the button a new scene is added to the storyboard of our application. This scene is a ListView Component that has a row for every available slate of games that will be played that night. In addition, each one of these rows is also wrapped in a TouchableHighlight Component, which allows them to respond to touches.

Any row that you touch results in an AJAX request being made to the Rotorobot API and the available players in that slate are displayed, sorted in descending order based on salary.

Our Experience

Getting something up and running with React Native was definitely a lot easier than expected. It was honestly as simple as using npm to install react-native-cli and then creating a new react native project using react-native init. The init function provides everything that you need to run a React Native application.

After your project has been setup it’s time for all of you Xcode naysayers to either bite the bullet and download Xcode or look for guidance in the form of another SaaS solution.

In order to help you out we’ve provided links to a couple:

If you’re old fashioned like us, and opted for the traditional route then you installed X-Code. The react-native init function creates an Xcode project file inside the ios folder in your new project’s directory. Simply open this up using Xcode and you are off to the races and ready to build/run your project at will.

There was only one minor gotcha that reared it ugly head while trying to get our application up and running. The React Native Packager runs underneath node and requires a port for its functionality. The default port that it runs on is 8081, and there is a chance that you could have a process already running on that port so your application will not be able to run. So before you try and run your Xcode project for the first time it is worth doing a quick check to make sure that port 8081 is free using:

sudo lsof -i :8081

Other than this minor inconvenience you should be all set for development!

After an hour or two of playing with React Native and building a pretty simple app, the power and simplicity of this framework became clear to us. First and foremost it was very refreshing to only have to run one or two npm commands and then be writing code in minutes afterwards. Setup was quick and painless which is always appreciated. During development we immediately noticed that developing our app felt just like developing for the web. Laying out the application was done using the CSS flex box, and was both quick and intuitive. Additionally, and probably more importantly, the framework just works. The UI components are native UIViews so naturally they look, feel, and behave the same as normal native components. We would definitely consider using React in the future and look forward to seeing how it improves and progresses from here.

AngularJS: Using dynamic content with $compile

One of the more opaque concepts about AngularJS is the process that converts a chunk of HTML from a template into “Angularized” HTML which is then inserted into the DOM. During this conversions, custom directives are replaced with their corresponding HTML content, Angular directives like ng-repeat are processed, and any event handlers of interest are wired up. As it turns out, Angular’s $compile service is what’s responsible for making the magic happen. OK great, but why is this interesting or important? Because leveraging the $compile service directly lets you take dynamic content and process it to enable Angular directives and behaviors.

Since examples are always helpful, here’s an admittedly contrived one that we’ll walkthrough. Imagine that we’re building a WordPress slideshow plugin and we want to support custom themes for individual slides. So in our plugin, a user would be able to modify the HTML that displays a slide, we’d save it to the database, and then retrieve that template when we render the slides. For arguments sake, let’s assume the “default” template for the slideshow looks something like this:

<div ng-class="slide.isActive ? 'active slide' : 'slide'">
  <slide-image ng-src="{{ slide.imageSrc }}"></slide-image>
  <div class="description" ng-bind="slide.description"></div>
  <starbar config="slide.starConfig"></starbar>
</div>

As you can see, we’ve got a few directives and by default we’re displaying some description. Generally, we could set this up by creating a “slide” directive that looks something like:

angular.directive('slide', function(){
    return {
      restrict: 'E',
      scope: {slide: '='},      
      templateUrl: 'slide.html',
    };
});

Great, nothing to crazy but with this setup there’s no way to supply dynamic HTML from our database to use in the template. In order to allow a custom template you’d just need to modify the directive to look something like:

.directive('slide', function($sce, $compile){
  return {
    restrict: 'E',
    replace: true,
    scope: {slide: '='},
    template: "<div></div>",
    link: function(scope, el, attr){
      angular.element(el).html(scope["slide"].template);
      $compile(el)(scope);
    }
  };
})

And then you’d be able to use it with:

<slide slide='config'></slide>

/** Javascript **/
$scope["config"] = {
  "template": "<h3 style='color: red; font-weight: bold' ng-bind='slide.description'></h3>",
  "description": "hello world!",
};

The key difference is that in the modified directive the template is inserted into the directive’s element using “angular.element(el).html(scope[“slide”].template);“ and then finally the $compile service is invoked to process the regular HTML to get Angular magic.

Anyway, as always questions or comments welcome!