The recent MVC landscape with Angular+React and Backbone+React

Sun Jun 8, 2014

This post might bring in some arguments for both parties that favour one of the framework then the other, but this will be a worth while comparision to take a look at the recent MVC landscape. Just to clarify - I'm still relatively new to Angular.

Lets be clear - React is a component that is designed and focused to replace the 'V' component under a MVC framework. The most recognise MVC frameworks are Backbone & Angular, and it's starting to increasingly standout that React is able to replace the 'V' component due to its virtual dom design, minimal exposure of real dom elements and data-binding handling. It is also proven from this post that Angular + React provides the fastest rendering.

To achieve fast render and low inital load speed, the design of the component hierarchy structure is relatively important. In Angular, React needs to be initiated at the controller. For Backbone, on the other hand needs to be initiated at the router.

Link to Angular+React Demo
Link to Backbone+React Demo

//Angular Example
angular.module('fasterAngular', []).
controller('mycontroller', ['$scope', function($scope){
   $scope.framework = 'ReactJs';
   $scope.data = [];
   // Fill the data map with random data
   $scope.refresh = function(){
       for(var i = 0; i < 1500; ++i) {
           $scope.data[i] = {};
           for(var j = 0; j < 5; ++j) {
               $scope.data[i][j] = Math.random();
           }
       }
   }

   $scope.refresh();

   $scope.$watchCollection('data', function(newValue, oldValue){
       React.renderComponent(
           MYLIST({data:newValue}),
           document.getElementById("fastRepeatArea")
       );
   })
}])

//Backbone example
$(document).ready(function () {
  new (Backbone.Router.extend({
    initialize : function () {
        var data = [];
        var refresh = function () {
          for(var i = 0; i < 1500; ++i) {
                  data[i] = {};
                  for(var j = 0; j < 5; ++j) {
                      data[i][j] = Math.random();
                  }
              }
          React.renderComponent(
            MYLIST({data:data}),
            document.getElementById("fastRepeatArea")
          );
        };
        refresh();
        $('button#refreshBtn').click(function () {
          refresh();
        });
    },
  }))();
});

React is initiated under the same flow and it would achieve the same render speed. This example can be further improved by delegating the data change event and click event to React or using mixins to listen to partial changes. Instead of having it through the Angular controller or Backbone router.

At this point, Angular+React and Backbone+React would be equivalent. Now lets take a look at the required components and initial loading speed.

According to Mithril, Angular takes 7.49ms to load and Backbone takes 18.54ms to load. Another important to note is Backbone is light weight but it still depends upon underscore & jquery. Those add up during initial script request!

I believe this pretty much dictates which combination is the go to framework for heavy web apps. Every second counts to keep your user on your site!

The contender in the market called Facebook React, I'll just call it React for short. React is a 'View' Framework. So in terms of a MVC, its the 'V' Component. Suprisingly React further simplified the entire landscape of 'View' framework. It only expose the real nodes that you have

Lets see how this will look like in React, ive also included the propeller react.backbone. It allows us to feed in backbone models into react and databind with mixin.


<!– html structure –>
<html>
  <body>
  </body>
</html>

//javascript code
/** @jsx React.DOM **/
‘use strict’;

define ([
  'jquery', backbone', 'react', 'react.backbone'
], function (
  $, Backbone, React,
) {

  var CommentComponent = React.createBackboneClass({
    var comments = this.props.collection.map(function(item) {
      return (
        {item.get('comment')}
      )
    });
    return (
      <div>
        {comments}
      </div>
    );
  });

  var StatsComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var MenuComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var WidgetLayout = React.createBackboneClass({
    componentWillMount : function () {
      this.collection = Backbone.Collection();
    },
    render : function () {
      return (
        <StatsComponent />
        <CommentsComponent collection={this.collection}/>
      )
    };
  });

  var AppLayout = React.createBackboneClass({
    render : function () {
      return (
        <div>
            <MenuComponent />
            <WidgetLayout />
        </div>
      );
    };
  });
  React.renderComponent({
    <AppLayout />,
    $('body')[0]
  });
});

The code base is smaller, easier to understand and to control. Now some may ask about Angular + React comparing with Backbone + React. For this I’ll leave it to next post, but this is now pretty clear Marionette is out of the game.

Goodbye Marionette & Hello React

Wed May 28, 2014

I have been developing a lot of large javascript web apps that requires a lot of subview management or componets and decentralize the model dependecies to better suit the component re-usability. It was not till early this year, I was still designing them with Backbone + Marionette. Now it's Backbone + React or Angular + React. For this post let's concentrate in comparing Backbone + Mariontte & Backbone + React. As we all know, Backbone 'View' itself is a design flaw. It had a lot of issues regarding its memory management and sub view management. Marionette on the other hand, did help solved the sub view management and memory issues by offering a wide range of common designs and design patterns to help build the application.

Although Marionette provided a decent way to handle layout, subviews and code management, it is still too dependent on Backbone and gets more complex upon further sub view nesting. In Marionette the view is represented as a tree, the subviews is also part of the tree, thus if to render the middle layer must destruct and a rebuilt must occur. As well as rendering multiple Marionette Layers and Regions, although these Marionette functionalites are really awesome which helped took out the pain in backbone. While nesting those components doesnt play nicely with each other and hard to decouple, causing the sub layouts and sub regions to have an event show fire before its parent fires the show event.

Consider in Marionette, you used a layout to display a widget on a page. Within the widget there is also a layout before it calls the itemview. In other words nested layout then itemview.

    
      
      <html>
        <body>
          
          
</body> </html>
//javascript code 'use strict'; define([ 'backbone', 'marionette' ], function( Backbone, Marionette ) { var AppLayout = Backbone.Marionette.Layout.extend({ template : '#some-layout-template' regions : { widget : '#widget', menu : '#menu' } }); var MenuItem = Backbone.Marionette.IteView.extend({ template : '#some-template' }); var CommentItem = Backbone.Marionette.ItemView.extend({ template : '#some-comment-template' }); var StatsItem = Backbone.Marionette.ItemView.extend({ template : '#some-template' }); var CommentsCompositeView = Backbone.CompositeView.extend({ template : '#some-comment-template', itemView : CommentItem }); var WidgetLayout = Backbone.Marionette.Layout.extend({ initialize : function () { this.collection = new Backbone.Collection(); }, template : '#widget-layout-template', regions : { stats : new Marionette.Region({ el : "#stats-region" }) comments : new Marionette.Region({ el : '#comment-region' }) }, onShow : function () { this.regions.stats.show(new StatsItem( model : someModel )); this.regions.comments.show(new CommentsCompositeView({ collection : this.collection })); } }); var layout = new AppLayout(); layout.render(); layout.widget.show(new WidgetLayout()); layout.menu.show(new MenuItem()); });

In this example we will run into a render issue with the sub region fire before the parent does.

Now came 2014 and there is a new contender in the market called Facebook React, I'll just call it React for short. React is a 'View' Framework. So in terms of a MVC, its the 'V' Component. Suprisingly React further simplified the entire landscape of 'View' framework. It only expose the real nodes that you have

Lets see how this will look like in React, ive also included the propeller react.backbone. It allows us to feed in backbone models into react and databind with mixin.

  
      <!– html structure –>
      <html>
        <body>
        </body>
      </html>
  
  
    //javascript code
    /** @jsx React.DOM **/
    ‘use strict’;

define ([
  'jquery', backbone', 'react', 'react.backbone'
], function (
  $, Backbone, React,
) {

  var CommentComponent = React.createBackboneClass({
    var comments = this.props.collection.map(function(item) {
      return (
        {item.get('comment')}
      )
    });
    return (
      <div>
        {comments}
      </div>
    );
  });

  var StatsComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var MenuComponent = React.createBackboneClass({
    render : function () {
      return (
        <div>
          {/* html template */}
        </div>
      );
    }
  });

  var WidgetLayout = React.createBackboneClass({
    componentWillMount : function () {
      this.collection = Backbone.Collection();
    },
    render : function () {
      return (
        <StatsComponent />
        <CommentsComponent collection={this.collection}/>
      )
    };
  });

  var AppLayout = React.createBackboneClass({
    render : function () {
      return (
        <div>
            <MenuComponent />
            <WidgetLayout />
        </div>
      );
    };
  });
  React.renderComponent({
    <AppLayout />,
    $('body')[0]
  });
});

The code base is smaller, easier to understand and to control. Now some may ask about Angular + React comparing with Backbone + React. For this I’ll leave it to next post, but this is now pretty clear Marionette is out of the game.

moving to jekyll

Sun May 25, 2014

Alright I'm a hacker and lazy to work myself around Wordpress - which is in php & dynamic content. Now recently migrated into Jekyll and use github to serve my pages - free CDN and fast static content! Woohoo

I will be re-building the site from scratch, so beware for the next couple of weeks

installing mysql-python on mac

Tue Feb 18, 2014

Awesome next challenge - running a flask server to connect to a MAMP [2.1.3] sql server on a mac (mavericks). Flask is a light weight python server and uses flask-sqlalchemy to connect. Installing mysql-python seems to be a challenge.


#assuming you've already installed xcode & homebrew
brew install mysql   #use brew install mysql --universal if your not using 64bit

Go to dev mysql
download the latest release and decompress the file.


cd /path/to/download/
tar -xvf mysql-*.tar.gz
cd /path/to/extract/
mkdir /Applications/MAMP/Library/include
cp -r include/* /Applications/MAMP/Library/include
cp -r lib/* /Applications/MAMP/Library/lib

export ARCHFLAGS="-arch $(uname -m)"
export PATH=$PATH:/Applications/MAMP/Library/bin
export DYLD_LIBRARY_PATH=/Applications/MAMP/Library/lib

sudo easy_install mysql-python

FYI: this line will cause trouble with git


export DYLD_LIBRARY_PATH=/Applications/MAMP/Library/lib

Rebooting your computer will clear it.

On a side note, when your connecting to the MAMP sql, python may complain mysql.sock is missing. It is located under


/Applications/MAMP/tmp/mysql/mysql.sock

Additional Source
mamp-python-mysql
stackoverflow

nginx with changed phpmyadmin directory setup

Mon Feb 17, 2014

Recently decided to setup a nginx / python / mysql lightweight backend to interact with a nodejs services. So decided to change phpmyadmin directory as well - i did run into 502 / 403 nginx errors, hope this post will help anyone who had the same issues too.

Setup process - assuming you are using ubuntu 12.04LTS


#install mysql & nginx
sudo apt-get install mysql-server mysql-client
sudo apt-get install nginx

#start nginx
sudo service nginx start

#install php5 & phpmyadmin
sudo apt-get install php5-fpm php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-xcache phpmyadmin

#reload php5
sudo service php5-fpm reload


#modify php5-fpm
sudo vi /etc/php5/fpm/pool.d/www.conf


#look for listen and modify as follow
[...]
;listen = 127.0.0.1:9000
listen = /tmp/php5-fpm.sock
[...]


#setup nginx config
sudo vi /etc/nginx/site-enabled/default


#add this after location /
[...]
location /pma {
    alias /usr/share/phpmyadmin/;
}

location ~ ^/pma/(.*\.(js|css|gif|jpg|png))$ {
    alias /usr/share/phpmyadmin/$1;
}

location ~ ^/pma(.+\.php)$ {
    alias /usr/share/phpmyadmin$1;
    fastcgi_pass unix:/tpm/php5-fpm.sock;
    fastcgi_index index.php;

    charset utf8;

    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT /usr/share/phpmyadmin;
}

#if you want to enable php site wide
location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/tmp/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
}
[...]


sudo service nginx reload

FYI: The most common 502 / 403 errors are due to this line in the nginx config file.


fastcgi_pass unix:/tmp/php5-fpm.sock; #example using unix:/var/run/php-fpm.sock;

Hopefully this post will help some travellers here.

Source
stackoverflow
howtoforge

nginx / nodejs stack setup

Mon Feb 17, 2014

So when you have an nginx + nodejs combo, you want to use nginx to port foward to nodejs

my nodejs uses forever to run on port 3000.

here is the nginx config setup


sudo vi /etc/nginx/site-enabled/default


#add this line before server { ... }
[...]
upstream app_nodejs {
        server localhost:3000;
}
[...]

#now in server {...}, assuming you want to map your url root to point to nodejs
location / {
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header Host $http_host;
               proxy_set_header X-NginX-Proxy true;

               proxy_pass http://app_nodejs;
               proxy_redirect off;
           }


Cheers

using git hooks to deploy server with forever

Mon Feb 17, 2014

If you love deploying with automation and you love the fact you dont need to touch your server (which you should!). I've setup this up on an ec2 ubuntu 12.04 LTS, shouldnt differ too much with other ubuntu versions. At this time of writing i'm setting up a nodejs / flask server

On your remote server


#install forever and give it global access
sudo npm install -g forever

#setup git bare at your deployment server
git clone --bare [repo url]

#add the hooks
#navigate into your git folder
cd path/to/repo/hooks
vi pre-receive

#!/bin/sh
echo "stopping server service"
service nodejs-www stop

vi post-receive

#!/bin/sh
echo "checkout the files"

branch=$(git branch | grep "*" | sed "s/* //")

if [ "$branch" = "master" ]
then
        echo "Master branch"
        git --work-tree=/home/ubuntu/app/www checkout -f
        echo "Successfully checked out master branch"
else
        echo "Not master branch"
fi

echo "start service"
service nodejs-www start

sudo chmod +x pre-receive;
sudo chmod +x post-receive;

FYI: Just make sure the folders are created for the "git --work-tree"


#navigate into init.d to create a service
cd /etc/init.d
sudo vi nodejs-www

#! /bin/sh
# /etc/init.d/nodejs-www
#

NAME=nodejs-www
APP=index.js
APP_DIR=/home/ubuntu/app/www
forever=/usr/local/bin/forever
export PATH=$PATH:/usr/local/bin/
LOG=/var/log/nodejs-www.log

case "$1" in
  start)
    cd $APP_DIR
    echo "Starting $NAME"
    #I detached the message to 'screen', it is not a requirement
    screen -d -m /usr/bin/sudo -u ubuntu $forever --minUptime 5000 --spinSleepTime 2000 -a -l $LOG start $APP
    #if to run a python server use
    #screen -d -m /usr/bin/sudo -u ubuntu $forever --minUptime 5000 --spinSleepTime 2000 -a -l $LOG start -c python $APP
    echo "Started $Name"
    exit 0
    ;;
  stop)
    echo "Stopping script $NAME"
    cd $APP_DIR
    /usr/bin/sudo -u ubuntu $forever stop $APP
    exit 0
    ;;
  list)
    echo "List"
    /usr/bin/sudo -u ubuntu $forever list
    exit 0
    ;;
  *)
    echo "Usage: /etc/init.d/nodejs-www {start|stop|list}"
    exit 1
    ;;
esac

exit 0

FYI: Many others were able to run forever directly without having "/usr/bin/sudo -u ubuntu" (ubuntu is the user account) or substituting it with "sudo". For my case on an amazon aws, without it, i ran into permission issues with forever and nodejs directory mapping issues.

A permission error similar to this:


fs.js:0
(function (exports, require, module, __filename, __dirname) { // Copyright Joy
^
Error: EACCES, permission denied '/root/.forever/pids/FepR.pid'
    at Object.fs.openSync (fs.js:410:18)
    at Object.fs.writeFileSync (fs.js:956:15)
    at writePid (/usr/local/lib/node_modules/forever/bin/monitor:13:6)
    at null. (/usr/local/lib/node_modules/forever/bin/monitor:46:5)
    at EventEmitter.emit (/usr/local/lib/node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js:332:22)
    at /usr/local/lib/node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/monitor.js:153:10

Now to wrap up the server side


sudo chmod a+x nodejs-www
cd /var/log
sudo touch nodejs-www.log
sudo chmod 777 nodejs-www.log

Add to rc.local to start upon server start


sudo vi /etc/rc.local

#!/bin/sh -e
service nodejs-www start
exit 0

For some you may need to change the rc.local permission to executable.

If i didnt miss anything this should it for the server

Now on client side


cd path/to/repo
git remote add deploy [remote server repo url]
git commit -am 'test deploy'
git push deploy master

This should be it, and the service should automatically stop and restart itself. If i missed anything let me know :)

Typical way of starting a startup

Fri May 24, 2013

Found this gold on the net. Felt should keep a record here :)

startup-cycle

Online Presence

Thu May 16, 2013

Previously my co-founder Andrew Boos followed up on the topic of difference of VCs and Angels. Continuo on the topic of start ups, this time lets cover online presence.

Your startup's online presence is relatively important to represent who you are, your cool product and how your customers can benefit from using it. In our startup Appfuel, it took us a good 2 months to get it straight. Resulting an increase of web traffic.

Spilling the beans:
1. Active social presence in
- Facebook page
- Twitter Profile
- AngelList

Your social presence represents what your startup is made out off. Using these social platforms to pump out messages, cool stories and keep you consumer of interest up to date.

There are great tools such as Buffer, if this then that to help you manage.

2. Landing Page
When someone first enters into your site, with average browser size of 1280px  * 720px on desktops and 320px *  480px on mobile. That is some relatively small space, but hey! That will determine if the user will continue reading on. You should spice up the landing page's image, and it will determine if the reader will continue reading on.

3. SEO ( Search Engine Optimization)
Another method to deliver organic traffic to your site are through searches. Make sure you have included meta tags of "description" and "keywords"; A short info in how you can help them; Submit your sitemap into the search engines.

4. Blog
Posting relavent information, tips, stories for the consumer drives relavent traffic and ultimately landing in as your customer.

There are tools such as hittail and google analytics to help you drill down to specific keywords that are driving traffic to your site.

As for ours we spiced up our blog a little bit just so the travellers can read the relavent posts, picture below.

IAMA - mortal - dev - show all

JavaScript Function Crib Sheet

Wed May 8, 2013

Getting Lazy! So created a javascript function cheat sheet to share with the travellers here. Hope it will be help many of you.

The cryptsheet includes these functions and can be found here : https://github.com/alfredkam/jsFunctions

General Laziness::
- jquery toggle string
- jquery enter keyup event

Mathematical Functions::
- n choose r
- Binomial Distribution
- Probability Mass Function (Useful when wanted to create a bell curve)
- Summation

If the function your missing is not listed, comment below and i may be able to write one.