JavaScript, Warthogs and Friends by Eugene Mutai

Twitter/Github - @kn9ts

LinkedIn:  http://bit.ly/eugene-in

Email: eugenemutai@gmail.com

 

http://bit.ly/rubyconf-jskn

Who is Eugene?

  • Beenleigh in the game for 3 years, s elf-taught-
  • If JavaScript was Naomi, I'd ask Ruth (guy tho)
  • Love building web apps
  • Nairobi JavaScript Community Lead
  • IHUB Consultant, VituMob.com CTO
  • Red color fanatic
  • A bit crazy in a cool way here and there
  • Game laws
 

http://bit.ly/mystory-eugene

JavaScript's History:

JavaScript was created in 1995 by Brendan Eich, an engineer at Netscape, and first released with Netscape 2 early in 1996. It was originally going to be called Live Script. but was renamed in an ill-fated marketing decision to try two capitalizes on the Popularity of Sun Microsystem's Java language - Despite the two having very little in common.

Its syntax comes from the Java and C languages, so many structures from Reviews those languages ​​apply two JavaScript as well.

Javascript is an object oriented dynamic language; it has types and operators, standard built-in objects, and methods.

 

It is Also a functional language.

Key differences is that JavaScript:

 

1. does not have classes; instead, the class functionality is accomplished by object prototypes . Note: as of ES6, classes have been introduced.

 

2. objects, giving functions the capacity to hold executable code and be passed around like any other object.

2

THIS IS FOR:
- Heard and confused about JavaScript and wanted to know what it really is
- Usual enthusiasts of JavaScript (refresher)
- Help you connect JS and Ruby (any other language that is used in backend programming)
- Here always learning all they can

- Wanted to prove jQuery is not JavaScript

 

 

USES ON THE BROWSER:
- Computation
- DOM manipulation (HTML and CSS crafting)
- Animations
- Game creations and graphics stuff
- Access your device's hardware eg. camera
- Make asynchronous request (AJAX)

 

Most things that ruby can't do and impress the user to stay and use your application

 

OTHERS:
- backend eg. Node.js
- robotics eg. Raspberry pi, Tessel, Auduino
- command line tools
- database language eg. Couchdb, RethinkDB
- phone apps (known as hybrid apps) eg. Cordova, titanium, appcelerator, ionic fw, nativescript

6

A LITTLE ABOUT HOW THE WEB WORKS

Request: Yo, Wha's up! Get me this!
 
  • Hey, here's the stuff (HTTP status code: 200)
  • Nothing like that here man! (200, 404)
  • I have no idea what you are talking about (405, 500)
 

HTTP Request and Responses

  • GET, HEAD - give me data
  • POST, PUT, PATCH - add/change some data

 

- If you follow REST API patterns (these are just the basics)

HTTP hypertext transfer protocol


- everything is a string
- stateless (dsnt know who sends or receives the request)
- uses the HTTP verbs to state exactly the action required

1

AJAX - asynchronous JavaScript and XML

asynchronous - page does not have to wait for the request to be completed


- Everything works as usual
- XML used to be the string format
- Now its JSON, and still XML in others

The API-XMLHttpRequest
 

- Makes a HTTP request
- Rails - request. xhr? (to check if it an AJAX request)
- JQuery wrappers $.ajax, $.get, $.post

How do we send data to the server?
- URL (a form of verb submission)

- POST (using forms or AJAX)
- JSON

 

How do we get data back?
- HTML

- HTML fragments
- Bootstrapping JavaScript (render the whole HTML so that JS can manipulate it)
- JSON

 

<div>
    Hey , <%= @username =>. Welcome back
</div>

<script type="text/javascript" src="bower_components/jquery/jquery.min.js">
</script>
<script>
    var tweets = "<%= @tweets.to_json =>";
    console.log(tweets);
</script>

In server, ruby compiling the template:

<script type="text/javascript" src="bower_components/jquery/jquery.min.js">
</script>
<script>
    var tweets = [{
        tweet_id: 921092010,
        message: "@jheneknights LOL"
    }, {
        tweet_id: 921092011,
        message: "Who wants to go for lunch? #hungry"
    }]

    $.each(tweets, function(single_tweet) {
       var add_tweet = '<div class="tweet">' + single_tweet.message + '</div>';
       $('div.news_feed').append(add_tweet)
    });
</script>

What the browser recieves:

JSON JavaScript Object Notation

 

- Do remember it comes as a string
- Can be passed both to server side and client side across almost all existent programming languages

JSON Example: Response from server

 
{
    "tweets": [{
        "tweet_id": 921092010,
        "message": "@jheneknights LOL"
    }, {
        "tweet_id": 921092011,
        "message": "Who wants to go for lunch? #hungry"
    }, {
        "tweet_id": 921092012,
        "message": "Am here at the RubyConf 2015 #awesome"
    }],
    "mete_data": {
        "total_tweets": 3,
        "tweet_id": [921092010, 921092011, 921092012],
        "request": 'GET',
        "status": 200,
        "time": 1878218281,
        "time_format": "UTC"
    }
}

Making an AJAX Request: Plain JS

 
var data = {
    ids: [12, 18, 27, 35, 41, 53, 66, 68, 72, 85, 94, 103, 111, 120, 133]
}

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(xhr) {
    if (xhr.readyState < 4 || xhr.status !== 200) {
        return;
    }

    // all is well
    if (xhr.readyState === 4) {
        console.log(xhr.responseText); // the list of tweets
        parseTweets(xhr.responseText)
    }
}

xhr.open('GET', 'https://your_awesome_url.com/tweet/', true);
xhr.setRequestHeader("Authorization", 'key=oNs3NZXPKF2_9NSAetkus');
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(data));

AJAX Request: using jQuery

var data = {
    ids: [12, 18, 27, 35, 41, 53, 66, 68, 72, 85, 94, 103, 111, 120, 133]
}

// A single line, jQuery you are awesome
$.get('https://your_awesome_url.com/tweet/', data, parseTweets, "json")
class TweetsController < ApplicationController
    respond_to :json

    def list_of_tweets
      @tw = Tweets.get(params[:user_id]), :only => [:id, :message, :time_created]

      respond_to do |format|
          format.json { render :json => @tw.as_json }
      end
    end

end

Returning a JSON response:

 

JavaScript: Receiving an AJAX request

var data = {
    ids: [12, 18, 27, 35, 41, 53, 66, 68, 72, 85, 94, 103, 111, 120, 133]
}

// A single line, jQuery you are awesome
$.get('https://your_awesome_url.com/tweet/', data, parseTweets, "json")

function parseTweets(tweets_from_server) {
    // Turn the string sent from server back to JSON
    var data = JSON.parse(tweets_from_server);

    var tweets = data.tweets;

    // loop through the tweets, displaying them
    $.each(tweets, function(single_tweet) {
        var add_tweet = '<div class="tweet">' + single_tweet.message + '</div>';
        $('div.news_feed').append(add_tweet)
    });
}

USES:
- single page applications (SPAs)
- no reloading/instant refreshing
- intuitive/good user xp
- data manipulation moved to client-side
- and saving data back to the server (without affecting progress of user)
- it is fast (sending mini chunks of data)

Web sites are turning into web apps.
Well! web apps are now F-22 Raptors (tech and engine spec).

 
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/moment/min/moment-with-locales.js"></script>
<script src="bower_components/lodash/dist/lodash.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="vendor/leaflet-0.7.3/leaflet.js"></script>
<script src="bower_components/leaflet-panel-layers/dist/leaflet-panel-layers.min.js"></script>
<script src="vendor/js/perfect-scrollbar.jquery.js"></script>
<!-- angular -->
<script src="bower_components/angular/angular.js"></script>
<!-- pusher -->
<script src="vendor/js/pusher.min.js"></script>
<script src="bower_components/pusher-angular/lib/pusher-angular.js"></script>
<!-- angular scripts -->
<script src="bower_components/angular-ui/angular-ui-router.js"></script>
<script src="bower_components/ng-table/dist/ng-table.js"></script>
<script src="bower_components/checklist-model/checklist-model.js"></script>
<!-- bower temp sidestep -->
<script src="vendor/js/angular-animate.js"></script>
<script src="vendor/js/angular-sanitize.js"></script>
<!-- app -->
<script src="app/app.js"></script>
<script src="app/common/api/ApiWrapper.js"></script>
<script src="app/common/api/ApiConfig.js"></script>
<script src="app/common/services/LoadingIndicator.js"></script>
<!-- layout -->
<script src="app/layout/ngulia-sidebar-menu.js"></script>
<script src="app/layout/app-title.js"></script>
<script src="app/layout/app-header.js"></script>
<script src="app/layout/app-body.js"></script>
<script src="app/layout/dropdown-menu.js"></script>
<script src="app/layout/sidebar-link.js"></script>
<script src="app/layout/back-button.js"></script>
<script src="app/layout/nav-menu.js"></script>
<script src="app/layout/control-panel.js"></script>
<script src="app/layout/Layout.js"></script>
<!-- user -->
<script src="app/user/user.js"></script>
<script src="app/user/UsersApi.js"></script>
<script src="app/user/UsersModel.js"></script>
<script src="app/user/ProfileCtrl.js"></script>
<script src="app/user/UserSessionsListCtrl.js"></script>
<script src="app/user/UserSessionsDetailtCtrl.js"></script>
<!-- authentication -->
<script src="app/authentication/authentication.js"></script>
<script src="app/authentication/login.js"></script>
<script src="app/authentication/LoginCtrl.js"></script>
<script src="app/authentication/LogoutCtrl.js"></script>
<!-- common services -->
<script src="app/common/services/Flash.js"></script>
<script src="app/common/services/Session.js"></script>
<script src="app/common/services/PusherWrapper.js"></script>
<script src="app/common/services/MapCoordinates.js"></script>
<!-- dashboard -->
<script src="app/dashboard/dashboard.js"></script>
<script src="app/dashboard/DashboardApi.js"></script>
<script src="app/dashboard/DashboardCtrl.js"></script>
<script src="app/dashboard/DashboardModel.js"></script>
<!-- map -->
<script src="app/map/map.js"></script>
<script src="app/map/MapConfig.js"></script>
<script src="app/map/MapApi.js"></script>
<script src="app/map/MapCtrl.js"></script>
<script src="app/map/MapService.js"></script>
<script src="app/map/MapStaticLayersModel.js"></script>
<script src="app/map/MapMarkersDynamicModel.js"></script>
<!-- Kolmarden -->
<script src="app/kolmarden/kolmarden.js"></script>
<script src="app/kolmarden/KolmardenCtrl.js"></script>
<script src="app/kolmarden/KolmardenMarkersModel.js"></script>
<!-- map alerts -->
<script src="app/map-alerts/mapAlerts.js"></script>
<script src="app/map-alerts/MapAlertsApi.js"></script>
<script src="app/map-alerts/MapAlertsModel.js"></script>
<script src="app/map-alerts/MapAlertsListCtrl.js"></script>
<script src="app/map-alerts/MapAlertsFilteredListCtrl.js"></script>
<script src="app/map-alerts/MapAlertsDetailCtrl.js"></script>
<script src="app/map-alerts/MapAlertsDispersingCtrl.js"></script>
<script src="app/map-alerts/map-alert-comments/MapAlertCommentsCtrl.js"></script>
<script src="app/map-alerts/map-alert-photos/MapAlertPhotosCtrl.js"></script>
<!-- rhino-reports -->
<script src="app/rhino-reports/rhinoReports.js"></script>
<script src="app/rhino-reports/RhinoReportsApi.js"></script>
<script src="app/rhino-reports/RhinoReportsModel.js"></script>
<script src="app/rhino-reports/RhinoReportsListCtrl.js"></script>
<script src="app/rhino-reports/RhinoReportsMapCtrl.js"></script>
<script src="app/rhino-reports/RhinoReportsDetailCtrl.js"></script>
<!-- supplies-requests -->
<script src="app/supplies-requests/suppliesRequests.js"></script>
<script src="app/supplies-requests/SuppliesRequestsApi.js"></script>
<script src="app/supplies-requests/SuppliesRequestsModel.js"></script>
<script src="app/supplies-requests/SuppliesRequestsListCtrl.js"></script>
<script src="app/supplies-requests/SuppliesRequestsDetailCtrl.js"></script>
<!-- assignments -->
<script src="app/assignments/assignments.js"></script>
<script src="app/assignments/AssignmentsModel.js"></script>
<script src="app/assignments/AssignmentsApi.js"></script>
<script src="app/assignments/AssignmentsCtrl.js"></script>
<script src="app/assignments/AssignmentsDetailCtrl.js"></script>
<!-- organizations -->
<script src="app/organizations/organizations.js"></script>
<script src="app/organizations/OrganizationsModel.js"></script>
<script src="app/organizations/OrganizationsApi.js"></script>
<!-- rangers -->
<script src="app/rangers/rangers.js"></script>
<script src="app/rangers/RangersApi.js"></script>
<script src="app/rangers/RangersModel.js"></script>
<script src="app/rangers/RangersListCtrl.js"></script>
<script src="app/rangers/RangersActiveCtrl.js"></script>
<script src="app/rangers/RangersDetailCtrl.js"></script>
<script src="app/rangers/RangersNewCtrl.js"></script>
<script src="app/rangers/RangersEditCtrl.js"></script>
<script src="app/rangers/RangerTrailLogsCtrl.js"></script>
<script src="app/rangers/RangerMapAlertsCtrl.js"></script>
<script src="app/rangers/RangerRhinoSightingsCtrl.js"></script>
<script src="app/rangers/RangerSuppliesRequestsCtrl.js"></script>
<!-- trialLogs -->
<script src="app/trail-logs/trailLogs.js"></script>
<script src="app/trail-logs/TrailLogsModel.js"></script>
<script src="app/trail-logs/TrailLogsApi.js"></script>
<!-- officers-in-charge -->
<script src="app/officers-in-charge/officersInCharge.js"></script>
<script src="app/officers-in-charge/OfficersInChargeModel.js"></script>
<script src="app/officers-in-charge/OfficersInChargeCtrl.js"></script>
<!-- commanders -->
<script src="app/commanders/commanders.js"></script>
<script src="app/commanders/CommandersApi.js"></script>
<script src="app/commanders/CommandersModel.js"></script>
<script src="app/commanders/CommandersListCtrl.js"></script>
<script src="app/commanders/CommandersDetailCtrl.js"></script>
<script src="app/commanders/CommandersNewCtrl.js"></script>
<!-- rhinos -->
<script src="app/rhinos/rhinos.js"></script>
<script src="app/rhinos/RhinosApi.js"></script>
<script src="app/rhinos/RhinosModel.js"></script>
<script src="app/rhinos/RhinosCtrl.js"></script>
<script src="app/rhinos/RhinosDetailCtrl.js"></script>
<script src="app/rhinos/RhinosNewCtrl.js"></script>
<!-- devices -->
<script src="app/devices/devices.js"></script>
<script src="app/devices/DevicesApi.js"></script>
<script src="app/devices/DevicesModel.js"></script>
<script src="app/devices/DevicesCtrl.js"></script>
<script src="app/devices/DevicesDetailCtrl.js"></script>
<script src="app/devices/DevicesNewCtrl.js"></script>
<script src="app/devices/DevicesEditCtrl.js"></script>
<!-- stations -->
<script src="app/stations/stations.js"></script>
<script src="app/stations/StationsApi.js"></script>
<script src="app/stations/StationsModel.js"></script>
<script src="app/stations/StationsCtrl.js"></script>
<script src="app/stations/StationsDetailCtrl.js"></script>
<script src="app/stations/StationsNewCtrl.js"></script>
<!-- blocks -->
<script src="app/blocks/blocks.js"></script>
<script src="app/blocks/BlocksApi.js"></script>
<script src="app/blocks/BlocksModel.js"></script>
<script src="app/blocks/BlocksCtrl.js"></script>
<script src="app/blocks/BlocksDetailCtrl.js"></script>
<script src="app/blocks/BlocksNewCtrl.js"></script>
<script src="app/blocks/BlocksEditCtrl.js"></script>
<!-- researchers -->
<script src="app/researchers/researchers.js"></script>
<script src="app/researchers/ResearchersApi.js"></script>
<script src="app/researchers/ResearchersModel.js"></script>
<script src="app/researchers/ResearchersCtrl.js"></script>
<script src="app/researchers/ResearchersDetailCtrl.js"></script>
<script src="app/researchers/ResearchersNewCtrl.js"></script>

King Julian's Response (Madagascar)

Mojo Jojo's response (powerpuff girls)

Front-end development would have become a nightmare without the progression it has undergone over the years

 

But it still is to beginners. Now you have to comprehend a lot more things that you could have a few years ago.

 
​THE PROBLEM:
  • Web sites are turning into Web apps
  • Code complexity grows as the web applications gets bigger
  • Assembly gets harder
  • Developer wants discrete JS files/modules
  • Clients want/need optimized code in just one or a few HTTP calls
  • Code blocks and tasks become repetitive
  • Code base too large for file to file debugging
  • Repackaging for production deployment (every time)
 
THE SOLUTION:
Front-end developers need a solution with:
  • Some sort of #include/import/require
  • ability to load nested dependencies
  • ease of use for developer but then backed by an optimization tool that helps deployment
  • Some form of repetitive task automation
  • Scaffolding
  • Linting
  • Automated realtime error/bug reports
  • Shipping ready development
 

Here's the nightmare slighly unraveled

THE AGE OF TOOLS:

  • Preprocessors and precompilers

  • Transpilers (ES6)

  • Task Automation

  • Package Management

  • Scaffolding

  • Versioning

  • Templating Systems
 

Preprocessors

 
  • CSS - SASS, LESS, POSTCSS, STYLUS

  • JS - COFFEESCRIPT

  • HTML - JADE

 
.bg-gradient {
  background: -moz-linear-gradient(top, #1e5799 0%, #7db9e8 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(100%,#7db9e8));
  background: -webkit-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
  background: -o-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
  background: -ms-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
  background: linear-gradient(to bottom, #1e5799 0%,#7db9e8 100%); 
}
.bg-gradient {
  @include background-image(linear-gradient(#1e5799 0%, #7db9e8 100%));
}

SASS (with it's sidekick COMPASS)

Gran ma's CSS

TranspilersCreated with the introduction of ES6

 
  • BABELJS

  • TRACUER (google)

  • TYPESCRIPT (microsoft)

2

TypeScript/Babel

class Student {
    fullname: string;
    constructor(public firstname, public middleinitial, public lastname) {
        this.fullname = firstname + " " + middleinitial + " " + lastname;
    }
}

interface Person {
    firstname: string;
    lastname: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstname + " " + person.lastname;
}

var user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

After Transpilation

var Student = (function() {
    function Student(firstname, middleinitial, lastname) {
        this.firstname = firstname;
        this.middleinitial = middleinitial;
        this.lastname = lastname;
        this.fullname = firstname + " " + middleinitial + " " + lastname;
    }
    return Student;
})();

function greeter(person) {
    return "Hello, " + person.firstname + " " + person.lastname;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);

Build Sytems

JavaScript back then (ES5) did not have importation

 
  • RequireJS

  • Browserify

  • Webpack

2
define(function (require) {
    var React = require('react');
    var Highcharts = require('highcharts');
    var $ = require('jquery');

    return React.createClass({
        getInitialState: function () {
            return {
                trades: app.models.instruments.gainers(5)
                    .sort(function (a, b) {
                        return a.percentageChange() + b.percentageChange();
                    }),
                options: {}
            }
        },

        render: function () {
            return (<div></div>);
        },
        componentWillUnmount: function () {
            $('.box').on('resize', this.resizeChart);
            app.models.instruments.off('sync', sync);
        }
    });

});

Task Automation Tools

 
  • GruntJS

  • Gulp

  • Brunch

  • Broccoli

  • Duo

  • Gobble

 
  • compiles your scripts, templates, styles (both transpilation and precompilation is taken care of here)
  • lints them
  • wraps the scripts and templates in common.js / AMD modules. (for build systems)
  • concatenates scripts and styles
  • generates source maps for concatenated files
  • copies assets and static files
  • shrinks the output by minifying code and optimizing images
  • watches your files for changes, reloads in browser
  • notifies you about errors via console and system notifications
4
grunt 
Running "jshint:gruntfile" (jshint) task
>> 1 file lint free.
 
Running "jshint:src" (jshint) task
>> 1 file lint free.
 
Running "jshint:test" (jshint) task
>> 1 file lint free.
 
Running "qunit:files" (qunit) task
Testing test/tiny-pubsub.html....OK
>> 4 assertions passed (23ms)
 
Running "clean:files" (clean) task
Cleaning "dist"...OK
 
Running "concat:dist" (concat) task
File "dist/ba-tiny-pubsub.js" created.
 
Running "uglify:dist" (uglify) task
File "dist/ba-tiny-pubsub.min.js" created.
Uncompressed size: 389 bytes.
Compressed size: 119 bytes gzipped (185 bytes minified).
 
Done, without errors.
 

Package 

Management

 

BOWER ALL THINGS

 
$ npm install -g bower

$ bower install jquery
$ bower install angularjs

Yo! 

Yo!
Wassup Dawg

Scaffolding! 

Yoeman!

1
$ npm install -g yo

$ npm install -g generator-webapp

$ mkdir my-yo-project

$ cd my-yo-project

$ yo webapp

Git & Github

 
$ git add -A

$ git commit -am "saving current snapshot"
$ git push origin master

Versioning Tool 

 
I'll never forget the day I woke up at 3am and said,
 
"I want to git rebase my LIFE!"
 

Huh?!?!?!!?!

 

Your job as a developer isn't just to develop, but to continually learn how to develop better.

1

@KN9TS

 

http://kn9ts.github.io/start-to-gulp

 

START-TO-GULP

 

Use now, Understand when curious!

Thank You. Much

JavaScript, Warthogs and Friends

By Eugene Mutai

JavaScript, Warthogs and Friends

  • 2,268