Wilson Mar bio photo

Wilson Mar

Hello!

Calendar YouTube Github

LinkedIn

Add routes to basic features included

US (English)   Norsk (Norwegian)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Estonian   اَلْعَرَبِيَّةُ (Egypt Arabic)   Napali   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean

Overview

This is a tutorial on how to make use of the hackathon-starter repo which uses SASS, Express, and several other commonly used packages to create a new Node app. Sahat Yalkabov’s repo comes with basic plumbing for processing several APIs along with account creation, login, contact form, and other basic “plumbing” features of websites.

This tutorial takes a “deep dive” approach by explaining each step’s responses, and adding NOTEs and PROTIPs commentary along the way.

The objective of the steps below is to add a top menu item a new route (page) to the boilerplate website.

Getting Started

  1. Get to URL:
    https://github.com/sahat/hackathon-starter

  2. Examine the branches, such as “es5” for ECMAscript 5.

  3. Log in to your GitHub account.

  4. Click Fork to copy the repo into your own account, such as:
    https://github.com/wilsonmar/hackathon-starter

  5. Install MongoDB if you haven’t already.

    Follow my tutorial on adding MongoDB in MacOS

  6. Open a Terminal shell window and make a folder such as:

    mkdir ~/gits
    mkdir wilsonmar

    But instead of “wilsonmar” specify your GitHub account name.

  7. Clone to your local folder (replacing wilsonmar in the example below):

    git clone –depth=1 https://github.com/wilsonmar/hackathon-starter -b es5

    The “–depth=1” limits the history of commits downloaded.

    Skip the “-b es5” if you want all the branches.

  8. cd to the folder

    cd hackathon-starter

  9. Instal Node on MacOS OSX by following my instructions:

  10. Download and install dependencies into the node_modules folder based on the package.json file:

    npm install

    NOTE: Some claim that “NPM” is a “bacronymic” abbreviation, a phrase constructed ex post facto to make itself, such as “npm is not an acronym”.

    Alternatively, use the yarn.lock file:

    yarn install
    
  11. Run the default app.js file:

    node install

    The response:

    ✓ Express server listening on port 3000 in development mode.
    ✓ MongoDB connection established!
    
  12. Press command+Tab to switch to a browser to URL:

    localhost:3000/

    You should see the website displayed just like at
    http://hackathonstarter-sahat.rhcloud.com

  13. Press command+Tab to switch to the Terminal to see the log:

    GET / 200 612.215 ms - -
    GET /js/main.js 200 130.849 ms - 71
    GET /js/lib/bootstrap.min.js 200 129.592 ms - -
    GET /favicon.png 200 128.995 ms - 1594
    GET /js/lib/jquery-2.2.4.min.js 200 138.446 ms - -
    GET /fonts/fontawesome-webfont.woff2?v=4.6.3 200 2.603 ms - 71896
    

Change landing page text

  1. Open another Terminal shell window.

  2. List the folders in the repo.

    PROTIP: This is a MVC (Model View Controller) project structure.

    • controllers contains home.js, user.js, contact.js, api.js
    • models contains User.js
    • public/fonts contains vendor fontawesome
    • public/js/lib contains bootstrap and jquery mimified libraries as backup.

    PROTIP: There are not HTML files in the views folder because they are generated from .pug files by the Pug template engine template engine (like Mustache) described at https://pugjs.org/api/getting-started.html.

    Pug is loaded by this Express template specification in app.js:

    app.set('view engine', 'pug');

    BTW, Pug used to be called “Jade”.

  3. Install Nodemon automatically restart the Node server if it detect changes in the app’s folder it watches.

    sudo npm install -g nodemon

    The response I got:

    /Users/mac/.nvm/versions/node/v6.8.1/bin/nodemon -> /Users/mac/.nvm/versions/node/v6.8.1/lib/node_modules/nodemon/bin/nodemon.js
     
    > fsevents@1.0.14 install /Users/mac/.nvm/versions/node/v6.8.1/lib/node_modules/nodemon/node_modules/fsevents
    > node-pre-gyp install --fallback-to-build
     
    [fsevents] Success: "/Users/mac/.nvm/versions/node/v6.8.1/lib/node_modules/nodemon/node_modules/fsevents/lib/binding/Release/node-v48-darwin-x64/fse.node" is installed via remote
    /Users/mac/.nvm/versions/node/v6.8.1/lib
    └─┬ nodemon@1.11.0 
    
  4. Install Pug:

    npm install pug –save

    WARNING: Notice the “pug@2.0.0-beta6” in the response.

    /Users/mac/.nvm/versions/node/v6.8.1/lib
    └─┬ pug@2.0.0-beta6 
      ├─┬ pug-code-gen@1.1.0 
      │ ├─┬ constantinople@3.1.0 
      │ │ ├── acorn@3.3.0 
      │ │ └── is-expression@2.1.0 
      │ ├── doctypes@1.1.0 
      │ ├── js-stringify@1.0.2 
      │ ├── pug-attrs@2.0.1 
      │ ├── pug-error@1.3.1 
      │ ├── void-elements@2.0.1 
      │ └─┬ with@5.1.1 
      │   └── acorn-globals@3.0.0 
      ├─┬ pug-filters@1.2.4 
      │ ├─┬ clean-css@3.4.20 
      │ │ ├─┬ commander@2.8.1 
      │ │ │ └── graceful-readlink@1.0.1 
      │ │ └─┬ source-map@0.4.4 
      │ │   └── amdefine@1.0.0 
      │ ├─┬ jstransformer@1.0.0 
      │ │ ├── is-promise@2.1.0 
      │ │ └─┬ promise@7.1.1 
      │ │   └── asap@2.0.5 
      │ ├── pug-walk@1.0.0 
      │ ├── resolve@1.1.7 
      │ └─┬ uglify-js@2.7.4 
      │   ├── async@0.2.10 
      │   ├── source-map@0.5.6 
      │   ├── uglify-to-browserify@1.0.2 
      │   └─┬ yargs@3.10.0 
      │     ├── camelcase@1.2.1 
      │     ├─┬ cliui@2.1.0 
      │     │ ├─┬ center-align@0.1.3 
      │     │ │ ├─┬ align-text@0.1.4 
      │     │ │ │ ├─┬ kind-of@3.0.4 
      │     │ │ │ │ └── is-buffer@1.1.4 
      │     │ │ │ ├── longest@1.0.1 
      │     │ │ │ └── repeat-string@1.6.1 
      │     │ │ └── lazy-cache@1.0.4 
      │     │ ├── right-align@0.1.3 
      │     │ └── wordwrap@0.0.2 
      │     ├── decamelize@1.2.0 
      │     └── window-size@0.1.0 
      ├─┬ pug-lexer@2.3.0 
      │ ├─┬ character-parser@2.2.0 
      │ │ └── is-regex@1.0.3 
      │ └─┬ is-expression@3.0.0 
      │   └── acorn@4.0.3 
      ├── pug-linker@1.0.1 
      ├─┬ pug-load@2.0.3 
      │ └── object-assign@4.1.0 
      ├─┬ pug-parser@2.0.1 
      │ └── token-stream@0.0.1 
      ├── pug-runtime@2.0.2 
      └── pug-strip-comments@1.0.1 
      

    Edit pug files

  5. Under the views folder, open for edit the home.pug file.

    See Pug/Jade Syntax Documentation by Example.

    BTW, If you have some HTML you want to convert to a .pug/.jade file, use
    http://html2jade.aaron-powell.com.

  6. Make an edit. From:

    hi Hackathon Starter

    to

    h1 My Hackathon Starter

  7. Save the file.
  8. Switch to the Node log window to see processing occur.

    GET / 200 328.854 ms - -
    GET /js/lib/jquery-2.2.4.min.js 304 24.451 ms - -
    GET /js/main.js 304 19.430 ms - -
    GET /js/lib/bootstrap.min.js 304 21.253 ms - -
    GET /css/main.css 200 16.631 ms - -
    

    Compare this to the first set.

  9. Switch to the browser and refresh the page to see changes.

    BTW, in the repo’s views/api folder is a separate .pug file for each API.

    Customize API Credentials

    The Hackathon Starter demo website has a script that loads secret passwords and other environment variables on the server. They are not included in the GitHub, for security reasons. There are bot constantly scanning GitHub to find cloud service credentials.

    PROTIP: Adopt a way to invoke the command to load the secret environment variables into memory automatically every time Node loads.

  10. Create a blank secrets-test.sh file and save it to a secure folder away from the repo, such as your user ~/.ssh folder where you keep your other private keys.

    NOTE: Many highly secure data centers do not allow use of USB storage devices.

    The “-test” part is to differentiate credentials used for different environments built. Each different file would be copied to the build folder for the corresponding environment.

  11. Use a text editor to view the repo’s controllers/api.js file.

    Each process.env (such as process.env.STRIPE_SKEY) refers to an environment variable.

    Keep the file open so you can refer back to it during this next step.

  12. Apply for your own keys from the APIs, as defined in the Hackthong-starter’s README.md file.

  13. Paste each key assigned into the secrets-test.sh file, ending up with content such as:

    mysql_host="http://host33663.rds.amazon-aws.com"
    mysql_un="amzn-app-db7293"
    mysql_db="rds-foxesandfences-db"
    mysql_pwd="K*$1x7B32auiWX91"
    pushover_key = "H75EAC19M3249!X2"
    google_maps_api_key="W69uHsUJZBPhsFNExykbQceK"
    

    Each line defines a differen environment variable.

  14. For execution in Linux, create a script hsstart.cmd to start the server after it loads the secrets file:

    
    node secrets.env
    node app.js
    

    For execution in Windows, create a PowerShell script to start the server after it loads the secrets file:

    
    ps load-secrets.ps1 secrets-test.sh
    node app.js
    

    If the .env file is protected by a password, you’ll need to enter that password.

  15. Assign permissions to run:

    chmon +x secrets-test.sh

  16. Run the file to load it into memory:

    ./secrets-test.sh

  17. Verify that the variables loaded:

    echo $USER

    PROTIP: Do not program the script to echo secrets.

    Update changes upstream

    In a Terminal shell window:

  18. Setup an upstream remote location to obtain future updates:

    git remote add upstream https://github.com/sahat/hackathon-starter

    Start Node app.js

  19. Install Nodemon globally, following instructions at:

    https://github.com/sahat/hackathon-starter/blob/master/README.md

    npm install -g nodemon

    The response:

    /usr/local/Cellar/node/6.3.0/bin/nodemon -> /usr/local/Cellar/node/6.3.0/lib/node_modules/nodemon/bin/nodemon.js
    /usr/local/Cellar/node/6.3.0/lib
    └── nodemon@1.9.2 
    

    -bash: nodemon: command not found

  20. Start app.js using nodemon (instead of node command) in order for changes to files cause Node to restart automatically and thus reflect changes made:

    nodemon -e js,jade app.js

    PROTIP: We use the “-e” parameter to watch .jade files to also watch .js files for changes as well as .js files.

    The response:

    Express server listening on port 3000 in development mode
    

    It’s important that you get this working as a baseline before making any changes.

  21. Open an internet browser (Chrome) to:

    http://localhost:3000
    

    The response should be what is shown on-line at the Live Demo site at http://hackathonstarter-sahat.rhcloud.com.

    Optional: Change ports

  22. On a Linux server, to change prots to listen on 8080, use a command such as:

    
    sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    

    Configure Login

  23. Click “CREATE ACCOUNT”.

    NOTE: The Starter includes coding for website visitors to create an account based on email and password entry.

    The information is stored in the MongoDB database created earlier.

  24. Click “LOGIN” to see that the Starter includes coding to process Login credentials from major identity vendors:

  25. Click on Sign in with Twitter.

    When you are redirected back, and your name should appear at the upper right corner.

    If this doesn’t appear, open a new browser tab, sign into Twitter, then return.

    PROTIP: The Starter makes use of the cookie stored on your browser when you sign into Twitter.

    CAUTION: In 2013 Twitter killed their API program by putting user caps for third-party Twitter clients and limiting the maximum number of users any outside client can ever have.

    This author wisely noticed that “by restricting access to its APIs, Twitter has in effect created a closed environment, where trolls can operate freely, because end-users do not have access to tools that would enable them to insulate themselves. It means the bad guys and the angry mob can game the system a lot easier.”

    TODO: Describe the Starter’s CSRF prevention techniques. CSRF prevention work by embedding additional authentication data into requests that allows the web application to detect requests from unauthorized locations.

  26. Click your name and select My Account.

    Notice the public details you provided to Twitter (Email, Gender, Location, etc.) is shown.

  27. Click CONTACT at the top menu.

    BTW, I filed an issue to suggest populating the contact form with information on the user.

    Configure API in menu

  28. Click “API EXAMPLES” at the top menu.

  29. Click Pinterest (near the bottom of the list).

  30. Click Okay to concede.

    When running in localhost, you’ll get a blank screen with a URL such as:
    https://localhost:3000/auth/pinterest/callback?code=112d913b9083d141

    PROTIP: In order for Pinterest to finish its work, there needs to be a public-addressible website.

    So let’s put the (unedited) website out there.

Website hosting

There are several options to host a Node website.

  • Locally
  • Locally within a Vagrant instance.
  • Heroku cloud
  • AWS

  • https://mlab.com/home?newAccount=1

Here we use docker-compose to get your Nodejs project in a server.

  1. Install Vagrant.
  2. Install Node and Docker in it.

  3. Open a new file containing this sample below and save it with name docker-compose-dev.yml

    version: '2'
    services:
     
      web:
     image: node:6.1
     volumes:
       - ./:/usr/src/app
     working_dir: /usr/src/app
     command: sh -c 'npm install; npm install -g nodemon ; nodemon -e js,jade app.js'
     ports:
       - "80:3000"
     depends_on:
       - mongo
     networks:
       - all
     environment:
       MONGODB_URI: "mongodb://mongo:27017/hackathon"
     
      mongo:
     image: mongo:3
     command: mongod --smallfiles
     networks:
       - all
     
    networks:
      all:
    

    PROTIP: The file above defines a service named “web” based on “node:6.1”. A storage volume is mounted to hold a working directory at “usr/src/app”. Semicolons act like separate Enter of commands we manually did above.

    The example above came from this article by MikeMichel (in Cologne, Germany), who explains:

    The “depends_on” clause specifies that the web services starting should depend on mongo db starting first. The Docker image requests version 3 of mongo. We want to

    The environment variable MONGODB_URI created is used by hackathon-starter to point to mongodb.

    The command to start mongod (Mongo Daemon) includes “–smallfiles” to reduce the initial size for data files so less diskspace is needed.

    The “all” under networks places both services in the same network.

  4. In a Termianl:

    docker-compose -f docker-compose-dev.yml up

    Limit APIs loaded

  5. You may want to comment out APIs that you don’t intend on using:

    atom package.json

    Replace atom with whatever text editor you prefer (subl for Sublime, vim, etc.).

    A short description of each package is here.

    Build Docker image

  6. Open a new file containing this sample:

    FROM node:6.1.0
     
    RUN mkdir -p /usr/src/app
    WORKDIR /usr/src/app
     
    COPY . /usr/src/app/
    RUN npm install
     
    CMD [ "node", "app.js" ]
    
  7. Save the file with name “Dockerfile” (no file extension) in your working directory.

  8. Build with your own dockerhubname:

    docker build -t yourdockerhubname/hackathon-starter:0.1

    Create a docker-compose.yml file to test if your just build image is running like expected.

  9. Duplicate the docker-compose.yml file.
  10. Edit the image to:

      web:
     image: yourdockerhubname/hackathon-starter:0.1
    

    Remove:

     volumes:
       - ./:/usr/src/app
     working_dir: /usr/src/app
     command: sh -c 'npm install; npm install -g nodemon ; nodemon -e js,jade app.js'
    
  11. Save the file.

  12. Run:

    docker-compose up

    Run the image

  13. Open an internet browser (Chrome) to:

    http://localhost:3000
    

    Change localhost to wherever you are hosting the server.

  14. Try again to Configure API above.

    Share Dock image

    If everything is fine:

    Replace your dockerhubname.

  15. If you want to keep your project private use a private repository instead.

  16. Push your image to dockerhub.com with a version number (such as “0.1”):

    docker push yourdockerhubname/hackathon-starter:0.1

    Now others can start your app locally using the docker-compose.yml file and running docker-compose up.

    Update using CI/CD

    See https://sloppy.io/from-dev-to-prod-with-nodejs-and-hackathon-starter-part-2/ which uses Wrker.

    TODO: Write instructions for using Shippable.

Add a new API

### viz.jade file #

  1. In a Finder window, navigate to the repo’s Views folder, home.jade file.

    Notice the Visual Studio Code editor recognizes .jade files.

  2. Open file home.jade using Visual Studio Code.

    Notice color-coding appears for different elements of the file.

    Alternately, you can use any text editor to edit the landing page:

  3. If you are not familiar with Jade/Pug templating markup, see
    http://jade-lang.com/tutorial

  4. Save to new file viz.jade.

  5. Examine the formatting:

    extends layout
     
    block content
      h1 Hackathon Starter
      p.lead A boilerplate for Node.js web applications.
      hr
      .row
     .col-sm-12
       h2 Heading
       p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
       p
         a.btn.btn-default(href='#', role='button') View details »
    


    The “.col-sm-2” is coding processed by Bootstrap JavaScript

  6. Edit the file to specify your page.

  7. Save the changes and exit.

    viz.js

  8. Edit the home.js file using Visual Studio Code or another text editor:

    The contents:

    /**
            * GET /
            * Home page.
     */
    exports.index = (req, res) => {
      res.render('home', {
     title: 'Home'
      });
    };
    
  9. Save to new file viz.js.

  10. Replace all “Home” with “Viz” and all “home” with “viz”.

    The end result:

    /**
            * GET /
            * Viz page.
     */
    exports.index = (req, res) => {
      res.render('viz', {
     title: 'Viz'
      });
    };
    
  11. Save and exit the file.

    Add Controller in app.js

  12. Edit the app.js file using Visual Studio Code or another text editor:

    Notice from the top of the file down:

    • The require statement brings in each library.

    • The .env.example file contains API keys and passwords.

    • ./config/passport

    • Controllers process top level menu items (Home, API, Contact, etc.)

  13. Read https://github.com/sahat/hackathon-starter#how-do-i-create-a-new-page

  14. Duplicate line (copy and paste):

    const contactController = require(‘./controllers/contact’);

  15. Edit to make a new Viz route, add:

    const vizController = require (‘./controllers/viz’);

    Add Custom route in app.js

  16. To add a new Viz route, add (above the Error Handler section):

    
    /**
     * Custom routes:
     */
    app.get('/viz', vizController.getViz);
    
  17. Save and exit the file.

    Define getViz

  18. Define getViz.

    Run to see changes

    Alternately, you may instead see some error messages:

    /Users/mac/gits/wilsonmar/predix-viz/node_modules/express/lib/router/route.js:196
         throw new Error(msg);
         ^
     
    Error: Route.get() requires callback functions but got a [object Undefined]
     at Route.(anonymous function) [as get] (/Users/mac/gits/wilsonmar/predix-viz/node_modules/express/lib/router/route.js:196:15)
     at EventEmitter.app.(anonymous function) [as get] (/Users/mac/gits/wilsonmar/predix-viz/node_modules/express/lib/application.js:481:19)
     at Object.<anonymous> (/Users/mac/gits/wilsonmar/predix-viz/app.js:221:5)
     at Module._compile (module.js:541:32)
     at Object.Module._extensions..js (module.js:550:10)
     at Module.load (module.js:458:32)
     at tryModuleLoad (module.js:417:12)
     at Function.Module._load (module.js:409:3)
     at Module.runMain (module.js:575:10)
     at run (bootstrap_node.js:352:7)
     at startup (bootstrap_node.js:144:9)
     at bootstrap_node.js:467:3
        

Enable basic features

  1. Email

  2. Google Analytics

  3. Search

Customize Look and feel

  1. Favicon

    Generate favicons for PC, Android, iOS, Windows 8 at http://realfavicongenerator.net/

  2. Use default APIs

    PROTIP: Invest in getting setup with the various APIs before you need them. Not only will you be prepared, you’ll be more knowledgeable and thus more creative when you understand the possibilities.

  3. Adopt a template from http://html5up.net/

    Each template come with index.html, images, css and js folders.

    https://github.com/sahat/hackathon-starter#custom-html-and-css-design-101

    Howeveer, Hackathon Starter CSS is coded to use gird and styles for the Bootstrap CSS framework, but these templates do not.

  4. Add another API

Add Algorithmia API

Algorithmia provides an API for calling Machine Learning algorithms as REST APIs.

https://github.com/sahat/hackathon-starter/issues/545

  1. Use an internet browser to apply for an account at algorithmia.com, then login with your password.

    No access to a local database is needed.

    Steps are influenced by https://www.npmjs.com/package/algorithmia

  2. In `package.json, add:

  3. In app.js add:

    const algorithmia = require("algorithmia");
    
  4. In app.js add:

    const algorithmia = require('algorithmia')({ key: process.env.ALGORITHMIA_KEY });;
    ...
    app.get('/api/algorithmia', apiController.getAlgorithmia);
    app.post('/api/algorithmia', apiController.postAlgorithmia);
    
  5. In .env file I created (not pushed to GitHub):

    ALGORITHMIA_API_KEY=asdfasdflksdf
    
  6. In controllers\api.js add:

    const Algorithmia = require('algorithmia');
    ...
    var client = algorithmia(process.env.ALGORITHMIA_API_KEY);
    
  7. Within folder views\api\ create file algorithmia.pug based on Clockwork, which has both input and output fields.

    extends ../layout
     
    block content
      .page-header
     h2
       i.fa.fa-phone
       | Algorithmia RGB2ColorName API
     
      .btn-group.btn-group-justified
     a.btn.btn-primary(href='https://algorithmia.com/algorithms/', target='_blank')
       i.fa.fa-check-square-o
       | Algorithmia.com
     a.btn.btn-primary(href='https://algorithmia.com/algorithms/wilsonmar/RGB2ColorName/', target='_blank')
       i.fa.fa-code-fork
       | RGB2ColorName
     
      h4 Send a text message
      .row
     .col-sm-6
       form(role='form', method='POST')
         input(type='hidden', name='_csrf', value=_csrf)
         .form-group
           .input-group
             input.form-control(type='text', name='rgb_numbers', placeholder='[Red,Green,Blue]')
             span.input-group-btn
               button.btn.btn-success(type='submit') Send
    

    From https://algorithmia.com/algorithms/wilsonmar/RGB2ColorName add:

    var input = [221,18,137];
    Algorithmia.client("simCyWJyqdmAV914trRikUuMJwp1")
            .algo("algo://wilsonmar/RGB2ColorName/0.1.23")
            .pipe(input)
            .then(function(response) {
              console.log(response.get());
            });
    

Add Google Maps API

In 2005 Google introduced their Maps API.

Before you do down this road (pun intended), know that there’s money involved.

google maps apis 284x353-c69.png

  1. Switch to the Google API Console at
    https://console.developers.google.com create a project and click “more” to expose all the Map APIs so you click each of the APIs in yellow to Enable them for your project.

  2. Click the “Credentials” menu item on the left to “Create Credentials” button for API Key. Browser key.

  3. Accept “Browser Key 2” or type in a name before clicking Create.

    We will return to specify referrer restrictions.

    AIzaSyDpk2I9IuO-ktQvqK56vfqprQu_i3X1bXE

  4. Copy the API key and paste it to replace the “…” in this JavaScript, then copy the whole set of lines and paste it near the bottom of body in HTML:

    <script async defer
    scr="https://maps.googleapis.com/maps/api/js?&key=...&v=3&callback=initMap">
    </script>
    

    Not http://maps.google.com/maps/api/js?sensor=true

    Refer to the JavaScript API at https://developers.google.com/maps/documentation/javascript/reference

  5. Get gmaps.js from Gustavo Leon’s
    https://github.com/hpneo/gmaps as described at this December 2015 blog.

    It’s an improvement over https://github.com/moshen/node-googlemaps

    Instructions also from:

    • https://dzone.com/articles/create-google-maps-gmapsjs

    Use a version in a CDN (Content Distribution Network):

    • https://cdn.jsdelivr.net/gmaps/0.4.24/gmaps.min.js from http://www.jsdelivr.com/projects/gmaps

    • http://hpneo.github.io/gmaps/ from https://cdnjs.com/libraries/gmaps.js/

  6. The GMap library requires jQuery:

    ≪script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
    

    QUESTION: Is this library in the Google CDN or CloudFlare CDN?

  7. Paste the CSS tag where the Google JavaScript library paints the #map:

    <div id="map"></div>
    
  8. Paste this at the top right under &LT;body> to receive the callback:

    var map = new GMaps({
     div: '#map',
     lat: -12.043333,
     lng: -77.028333
    });
    

    Instead of Google’s:

    <script>
    var map;
    function initMap(){
       map = new google.maps.Map(document.getElementById('map'), {
         center: {lat: 40.1234567, lng: -73.1234567},
         zoom: 13
       });
       // TODO: Use a database instead:
       var locations= [
          {title: 'Park Ave', location: {lat: 40.1234567, lng: -73.1234567}},
          {title: 'Chinatown', location: {lat: 40.1234567, lng: -73.1234567}}
       ];
    }
    </script>
    
  9. PROTIP: One good way to learn this is Google’s FREE 12 hour video course at Udacity which builds a Real Estate listing app.

  10. Install wrapper for asynchronously used Google Maps API:

    npm install googlemaps

    The response:

    /usr/local/Cellar/node/6.3.0/lib
    └─┬ googlemaps@1.11.1 
      ├── check-types@1.3.2 
      ├── qs@4.0.0 
      ├─┬ request@2.44.0 
      │ ├── aws-sign2@0.5.0 
      │ ├─┬ bl@0.9.5 
      │ │ └─┬ readable-stream@1.0.34 
      │ │   ├── core-util-is@1.0.2 
      │ │   ├── inherits@2.0.1 
      │ │   ├── isarray@0.0.1 
      │ │   └── string_decoder@0.10.31 
      │ ├── caseless@0.6.0 
      │ ├── forever-agent@0.5.2 
      │ ├─┬ form-data@0.1.4 
      │ │ ├── async@0.9.2 
      │ │ ├─┬ combined-stream@0.0.7 
      │ │ │ └── delayed-stream@0.0.5 
      │ │ └── mime@1.2.11 
      │ ├─┬ hawk@1.1.1 
      │ │ ├── boom@0.4.2 
      │ │ ├── cryptiles@0.2.2 
      │ │ ├── hoek@0.9.1 
      │ │ └── sntp@0.2.4 
      │ ├─┬ http-signature@0.10.1 
      │ │ ├── asn1@0.1.11 
      │ │ ├── assert-plus@0.1.5 
      │ │ └── ctype@0.5.3 
      │ ├── json-stringify-safe@5.0.1 
      │ ├── mime-types@1.0.2 
      │ ├── node-uuid@1.4.7 
      │ ├── oauth-sign@0.4.0 
      │ ├── qs@1.2.2 
      │ ├── stringstream@0.0.5 
      │ ├── tough-cookie@2.3.0 
      │ └── tunnel-agent@0.4.3 
      └── waitress@0.1.5 
      

    Other node libraries:

    • https://github.com/mikeal/request

    • https://github.com/danwrong/restler

    • https://prazjain.wordpress.com/2012/04/19/maps-example-with-google-maps-and-nodejs/ uses libraries express, ejs, geohash to latitude and longitude coordinates.

  11. Define Proxy.

  12. Get geocode (physical address) from IP Address.

  13. Display Static Map.

  14. Place Search.

  15. Calculate distance.

    JavaScript changes

    When coding JavaScript please keep in mind the rules specified in this Style Guide:

    https://github.com/airbnb/javascript

    Reference these:

    • http://www.javascripting.com/ provides a database of JavaScript libraries.

    • http://www.javascriptoo.com/ provides a directory of JavaScript libraries with examples, CDN links, statistics, and videos.

    • http://sahatyalkabov.com/jsrecipes/ provides JavaScript tutorials for backend and frontend development.

    Add tests

MLab

  1. Open the mlab.com website.

  2. If you don’t already have one, click the Sign up button and fill in your user information then hit Create account.

  3. From the dashboard, click on ⚡ Create new (database) button.
  4. Select any cloud provider. I usually go with AWS East, the default.
  5. Under Plan, click on Single-node tab, and select Sandbox (shared, 0.5 GB) since it’s free.
  6. Leave MongoDB version as is 3.0.x (MMAPv1)

    QUESTION: What happened to 2.4.x ?

  7. Enter Database name* for your web app.

    https://api.mlab.com/api/1/databases/[db]/collections/[collection]?apiKey=[key]

    [db] is replaced

    [collection]

    [key]

  8. Click on ⚡Create new MongoDB deployment button
  9. Now, to access your database you need to create a DB user
  10. Click to the recently created database

    You should see the following message:

    A database user is required to connect to this database. Click here to create a new one.

  11. Click the link and fill in DB Username and DB Password fields

  12. Use a text editor to update database credentials in .env file:

    mongodb://localhost:27017/test
    

    use the following URI with your credentials:

    db: ‘mongodb://USERNAME:PASSWORD@ds027479.mongolab.com:27479/DATABASE_NAME’

    Note: As an alternative to mLab, there is also https://www.compose.io/

Video Learning resources

Here are my notes on Pluralsight’s Node.js learning path

### Beginner classes

Other Learning resources

More on front-end styling

This is one of several topics:

  1. UI Design Systems
  2. Text Editors
  3. Markdown text for GitHub from HTML
  4. 508 Accessibility

  5. gRPC (g___ Remote Procedure Call)
  6. HTTP/2 Transition Project Plan

  7. Front-end UI creation options
  8. Docusaurus static website generator
  9. Static websites
  10. JAM Stack Website Project Plan
  11. Jekyll Site Development
  12. Gatsby app generator

  13. Website styles
  14. Website Styling
  15. VueJs front-end framework

  16. Protractor to automate testing of Angular and other web pages

  17. Email from website
  18. Search within Hyde format Jekyll websites
  19. Windows Tile Pin Picture to Website Feed

  20. Data Visualization using Tableau