learning

Learning with practice, test, and course curriculum code.

View on GitHub

Colt Steele’s Web Development Bootcamp on Udemy Notes

Syllabus

  1. Course Intro
  2. Intro to Front End
  3. Intro to HTML
  4. Intermediate HTML
  5. Intro to CSS
  6. Intermediate CSS
  7. Bootstrap
  8. Bootstrap 4
  9. Bootstrap, Flexbox Layout
  10. JavaScript Basics
  11. JavaScript Control Flow
  12. JavaScript Functions
  13. JavaScript Arrays
  14. JavaScript Objects
  15. DOM Manipulation
  16. JavaScript Events
  17. Color Game Project
  18. Intro to jQuery
  19. Advanced jQuery
  20. Todo List Projects
  21. Patatap Clone
  22. Backend Basics
  23. The Command Line
  24. Intro to NodeJS
  25. Intro to Server Side Frameworks
  26. Intermediate Express
  27. Working with APIs
  28. YelpCamp Basics
  29. Databases
  30. YelpCamp Data Persistence
  31. RESTful Routing
  32. Data Associations
  33. YelpCamp Comments
  34. Authentication
  35. YelpCamp Authentication
  36. YelpCamp Cleaning Up
  37. YelpCamp Update and Destroy
  38. YelpCamp UI Improvements
  39. Git and Github
  40. Deploying
  41. JavaScript: The Tricky Stuff

02 Introduction to Front End

03 Introduction to HTML

04 Intermediate HTML

Introduction to CSS

06 Intermediate CSS

07 Bootstrap

08 Bootstrap 4

09 Layout

10 JavaScript Basics

11 JavaScript Control Flow

12 JavaScript Functions

13 JavaScript Arrays

14 JavaScript Objects

15 JavaScript DOM

16 JavaScript Events

17 Color Game Project

See the project here

18 jQuery Intro

jQuery is a frontend javaScript library that assists in selecting, styling, and manipulating DOM elements.

Including

Include script src in HTML Document

Selecting

jQuery selects dom elements with the $() function.

Manipulating

$() has several common methods to manipulate HTML

19 jQuery Advanced

jQuery Events

jQuery lists have methods to simplify JavaScript Events

$('.selector').*event*(/*function to run on click*/);

Also use $('this') instead of this in callback functions.

If callback is passed an event arg, can be used to listen for specific key

$('input').keypress(function(event) {
    console.log(event.which);
    // Returns char key code
});

jQuery Event Types

jQuery has lots of events on documentation

jQuery Effects

Animations on stuff

$("button").on("click", function() {
    $("this").fadeOut(duration, callback);
});

Animations

20 Todo List App

View the project here

21 Patatap Clone

SKIPPED

22 Backend Basics

Servers decide what content to send to clients over the internet.

You ask for a web page, and you get one back.

Types of sites

Stack: the languages and technologies that an app uses (front + back ends)

Full Stack developers write code on all parts of the stack: front and back ends

HTTP In Depth (Postman)

Postman can be used to send customizable HTTP requests without worrying about rendering in the browser.

23 Command Line

Lets you interact directly with the computer by telling it what to do with commands

24 Intro to Node

Node is a JavaScript engine for a backend server, which can integrate with the NPM collection of libraries.

Using Node

Node is run in the console by running command node

Node Package Manager

Lets you use pre-written code libraries, or packages, super easily. (No CDN, automatic dependency management)

to use NPM, run npm install in command line from project directory, then in js file type const pkg = require('pkg');

package.json

Used by NPM to keep track of module dependencies, and to easily be able to install them. Lets you send a “shopping list” instead of shipping all the ingredients.

Using NPM

  1. npm init initializes package.json by asking questions
  2. npm install installs packages to node_modules

Types of Dependencies:

Automatic Server Restart (Nodemon)

Normally, you have to run node app.js every time you make a change in order to see it.

Nodemon automatically detects changes and can run scripts when files are changed.

  1. npm i -g nodemon installs nodemon globally, lets you run as command
  2. add npm nodemon app.js to npm scripts
  3. run npm scripts

25 Express Framework

Frameworks provide a baseline way of doing things in code. You must write code that conforms to the specifications of the framework.

You can call a Library, but a Framework calls you.

Express Framework is a server framework which receives requests and returns a response

Routing

Routes: runs one bit of code vs another depending on request

// client requests / root page
app.get('/', function(request, response){
    res.send(); // what to send to client
});
//app.get(*, function(req,res)) {} lets you catch-all (404)

Routing Parameters: lets you use URL to create DRY code instead of creating an app.get() for every single item app.get('/r/:subredditName/comments/:id/:title/', func..) Gets passed back to server via req.params{subredditName: soccer}

26 Intermediate Express

Instead of rendering single lines, or typing entire HTML documents into a res.send function, you can use res.render to return an entire file (HTML or EJS).

Render searches for a file by default in the views directory, where you can put all the served files an partials

EJS (Embedded JavaScript) is a templating language that expands JS and HTML.

To use JavaScript in an EJS file, use syntaxes:

To pass variables into a template, use the render method’s second parameter to pass an object. res.render('home.ejs', {user: req.ip});

Including files

Most assets like images, css, and js files go in a separate directory. Can be served by using app.use(express.static('public')); in app.js. Still must link files. Should reference them in root, since public directory ‘explodes’ in root.

Partials are incomplete, but reusable sections of a page like navbars and footers. Goes in views <%- include('partials/navbar') %>

Post Requests

Most routing is done with app.get, but you can also run code when a post request is made, like from a form

  1. Create a route app.post('/route', (...) => {...}), which will receive post requests
  2. Create a form that points to that route
  3. Form values are returned to server in req.body which must be parsed by NPM Package body-parser

27 Working with API’s

Application Programming Interfaces API’s allow you to connect with other applications instead of doing everything from scratch.

Transferring Data

API’s send data over HTTP using either XML or JSON or some other technologies

API Requests with Node

You can make a request using a browser’s URL bar, or using builtin libraries in languages.

To request using Node, use request or axios

Request is deprecated! Use Axios instead.

// first install with npm
const request = require('request');

request('https://url.tld', function (error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
})


// or use axios
const axios = require('axios'); // npm install axios
axios({
    method: 'get',
    url: '/url',
})
    .then(response => {
        console.log(response);
    })
    .catch(error => {
        console.log(error);
    })
    .finally(() => {
        // always executed after the request
    });

After getting JSON data from API, must be converted from JSON string into object format. const data = JSON.parse(body);

You can then ‘drill down’ and get a particular piece of information from the data. const info = data["list"]["towns"];

28 YelpCamp 1

Add GET and POST routes, EJS pages, submission form, etc.

29 Intro to Databases

Collection of information / data

SQL (Relational) Database

Tabular, flat databases that work by creating relationships to other tables (Entity Relationship Diagram)

Relationships are specified in their own “join” table, using a primary key from each table.

Cannot easily add fields; would have to do for each user. Patterns have to be defined ahead of time

NoSQL (Non-Relational) Database

Patterns do not have to be strictly adhered to; more flexible. Easier to update Formatted as BSON: Similar to JSON

MongoDB

Most popular NoSQL software

Collection == Table (should be plural and lowercase) Document == Row / Record / Object Fields == Column / Field / Attribute

Concepts in SQL vs NoSQL

Commands

help // shows commands
mongo // runs mongo shell (write commands)
mongod // runs mongo daemon (basically server; accepts commands)
`mongod --dbpath="C:/Program Files/MongoDB/Server/4.2/data"` // run as administrator



show dbs // show existing dbs
use *db* // sets working db, or create new empty db 
db // Shows working db

show collections // show
db.createCollection(name, options)
db.*collection*.*method*() // methods can be chained
// === collection methods ===
db.*collection*.insertMany([
    *document*,
    {key: 'value', key: 'value'}
])
.insert([{key: 'value'}]) // insert one or more documents
.find() // select *
.findOne({key: 'value'}) // find({}).limit(1)
.find({key: 'value'}) // find matching documents
    // Find Operators: $ {key: {$gt | $gte | $lt | $lte} }
    .pretty() // pretty print output
    .limit(*n*) // limits number of results
    .sort({id: *1 | -1*}) // sort by id attribute,
    .forEach((doc) => {}) // run code for each result 
        print() // like console.log
    .map((doc) => {}) // return something from each entry
.count() // returns number of results
.update({find}, {new data}, {options}) // find and replace
    //  Options: "upsert" creates if does not exist yet
    //  new data: an object, or an operator
        //  $set: {} does not replace (adds)
        //  $inc: {} increments fields
        //  $rename: {} key to new key
.remove({key: 'value'})

Mongoose

Object Data Mapper; Helps to interact with MongoDB from within Node; like jQuery for DOM. Creates Schema for applications.

npm install mongoose

const mongoose = require('mongoose');

//               protocol://url/database
mongoose.connect('mongodb://localhost/testing')

// Creates outline for entity
const customerSchema = new mongoose.Schema({
    name: String,
    age: Number,
    personality: String
});

// Creates instance (document, object) from schema
// (collection, schema)
// this creates a model with methods!
const Customer = mongoose.model("customers", customerSchema);

Customer.find({}, (err, item) => {
    if (err) {
        console.log("===ERROR===\n" + err);
    } else {
        console.log("Items!\n" + item);
    }
});

// New Customer and Save customer both at once
Customer.create({
    name: "Julian",
    age: 20,
    personality: "Giving",
    isTrending: false // this will get thrown out since not in schema
}, function(err, item) {
    if (err) {
        console.log("===ERROR===\n" + err);
    } else {
        console.log("Added to Database:\n" + item);
    }
});

30 YelpCamp + MongoDB

Improve styling, add and integrate MongoDB

31 RESTful Routing

A pattern for defining routes; maps HTTP requests to CRUD

REST: REpresentational State Transfer

RESTful Routes

Patterns for an app that interacts with server

These can connect to:

You will also have nested routes, like creating a comment on a post (associated data)

32 Data Associations

Relationships between collections in database Example:

Types of Relationships

Associations in Mongoose

Can be made with either embedding or referencing

Embedded Data

When creating the schema for one model, make the schema of the other model one of the attributes.

// Configure Schemas
const postSchema = new mongoose.Schema({
    title: String,
    content: String,
});

const userSchema = new mongoose.Schema({
    email: String,
    name: String,
    posts: [postSchema] // One User to Many Posts
});

// Then initialize containing model
const User = mongoose.model('users', userSchema);
const newUser = new User({
    name: 'Heck',
    email: 'heck@heck.com',
    posts: [
        {
            title: 'Heck a bit harder',
            content: 'it\'s good exercise'
        }
    ],
});
// Add to contained model
newUser.posts.push({
    title: 'Hecking to the Heck',
    content: 'You should heck as much as you can'
});

Referenced Data (Object References)

Instead of embedding the entire schema, you can use references to a mongodb document’s id

const userSchema = new mongoose.Schema({
    email: String,
    name: String,
    posts: [
        {
            // References an object's ID
            type: mongoose.Schema.Types.ObjectId,
            // collection (same as model's string)
            ref: 'posts'
        }
    ]
});

Then, you push instances of the post to user’s posts array.

After that, when you want to use the referenced object, you do Model.findById(id).populate('collections').exec((err, item) => {}).

module.exports

You can split up files into multiple parts by using export and require.

You can export an object, almost like a return value from a file using module.exports = {};.

33 Refactoring YelpCamp

34 Authentication

Authentication is how a user proves who they are on the web (passwords, accounts)

Sessions

Provides State to HTTP; saves whether the user is still logged in.

Libraries

Passport.js

Authentication library for Node.js, already built with support for MANY types of authentication

35 Yelpcamp 4 | Authentication

36 Yelpcamp 5 | Data Association

37 Authorization

Once you know who someone is, you can find out what they are allowed to do.

Yelpcamp 6 | Authorization

38 Yelpcamp 7 | UI Improvements

39 Git, Github

Git

Version Control System

Github

Online platform that uses git to share and version code.

Git Commands

Main commands you will use

40 Deployment

Having the app constantly running on a server and available anywhere

Cloud Deployment Tools

Companies that will let you rent server space for apps

Heroku

Free hosting platform with many language choices, good for NodeJS

  1. Create account with Heroku
  2. Download Heroku CLI, run heroku login

    package.json should have npm start script with node app.js

  3. Create Git repository & add files
  4. Create heroku app, heroku create
    • Creates git remote
  5. Commit & Push changes to heroku
    • git push heroku master
  6. View error messages heroku logs

    OR you can connect a github repo to heroku

Environment Variables

It is good to separate certain things like production and development

Environment Variables let you have different values depending on the place of deployment

Accessing Environment Variables

Reference environment variables by writing process.env.VARNAME

Creating Environment Variables

There are many ways to create environment variables

  1. Use a .env file which you .gitignore to prevent exposing data
    • use npm package dotenv to grab data from that file
  2. use the command export to save a variable as a computer environment variable
    • export VARNME=value
  3. (Heroku) Go into settings > config variables and add a new environment variable
    • or, use command line: heroku config:set VARNAME=value

41 Advanced JavaScript

JavaScript has some tricky concepts, outlined below

this keyword

Context-dependent value with implications for OOP

Global Context

When this is in a function, or is not in an object

Object / Implicit Context

When this is in an object or method, this refers to closest parent object.

Explicit Binding Context

You can explicitly set the value of this to use in a function.

Method Parameters Invokes?
Call this,1,2,3 Yes
Apply this,[1, 2] Yes
Bind this,1,2,3 No, later

obj.method.apply(thisObj, [arg1, arg2]);

const boundMethod = obj.method.bind(this, arg1);

boundMethod(arg2);

setTimeout(() => {...}.bind(this), 1000)

new Context

When creating an object with the new keyword, this refers to created object.

function Person(name) {
    this.name = name;
}

“use strict”;

Subset of JavaScript with stricter rules, designed to prevent bugs and be more secure.

Object Oriented Programming

Programming paradigm based on the idea of objects

New Keyword

Keyword used to create objects

  1. Creates an empty object
  2. Sets this in function to be the empty object & populates fields
  3. Adds implicit return this to the end of constructor
  4. Adds property called __proto__, linking to constructor prototype

Constructor Functions

A class has a function that creates an instance of an object, each with similar properties

function House(beds, baths, sqft) {
    this.beds = beds;
    this.baths = baths;
    this.sqft = sqft;
    return this;
}
const myHouse = new House(2, 2, 1000);

Extending a Constructor (Pre-ES6)

You can apply/call a base constructor inside another constructor to extend a class and make the subclass inherit its parent’s properties

function Person(name) {
    this.name;
}
function SmallPerson(name, height) {
    Person.call(this, name); // extends Person constructor
    this.height = height;
}
function WeirdPerson(name, personality) {
    Person.apply(this, arguments);
    this.personality = personality;
}

Prototypes

Objects share methods and properties through the prototype chain.

ES6 Object Oriented Programming

ES6 adds new syntax to JavaScript’s OOP functionality

class Human extends Animal {
    constructor(name) {
        super(arguments); // runs parent's constructor
        this.#name = name; // private var #
        this.type = human;
        this.legs = 2;
        this.sound = "hello";
        this.speak = this.speak.bind(this);
    }
    speak() {
        console.log(`${this.name} says ${this.noise}`);
    }
    get name() {
        return this.name;
    }
    set sound(newSound) {
        this.sound = newSound;
    }
    static method() {   // static means only class can use
        return 'waaah'  // instances cannot use
    }                   // similar to Math.method()
}

https://www.sitepoint.com/javascript-private-class-fields/

Closures

A nested function, where the inner function depends on values from the outer function

function adder(a) {
    return function(b) {
        return a + b;
    }
}
adder(5)(10); // 15; runs both funcs at once


function classRoom() {
    const instructors = ['colt', 'elie'];
    return {
        getInstructors: function() {
            return instructors;
        },
        addInstructor: function(newInstructor) {
            instructors.push(newInstructor);
            return instructors;
        }
    }
}
const c1 = classRoom();
c1.getInstructors(); // returns array

To Do:

Resources