#100DaysOfCode Round 3

⭐ Round 3 Projects ⭐


Today I finished R3 D100 of 100DaysOfCode! 🎉 Thanks to all the amazing content creators including freeCodeCamp, Codecademy, FrontendMasters, FluxSauce, ste_grider, and wesbos! https://virtual.github.io/100daysofcode/

Favorite course of the year from ste_grider: Microservices with Node JS and React. Great lessons on learning Docker and Typescript and actually integrating them into projects. I love the hands-on approach and “improving code” progression. 👏 https://www.udemy.com/course/microservices-with-node-js-and-react/

Interested in test-driven design TDD? There’s so much information in this course: Node.js: Testing and Code Quality from FluxSauce! I learned about tools I didn’t even know existed for auditing and reporting on code coverage. https://www.lynda.com/Node-js-tutorials/Node-js-Testing-Code-Quality/587672-2.html

If you’re interested in doing 100DaysOfCode, start with a list of possible projects you’re interested in working on. It’s helpful when you finish something (or are a bit bored) & need a change of pace. Great options: javascript30 freecodecamp

R3 Day 100: 2020-06-28 Sunday

Microservices Ticketing Site

Auth service

Setup K8s early on!

Skaffold

R3 Day 99: 2020-06-27 Saturday

addMarker(mappable: User | Company): void { }

interface Mappable {
  location: {
    lat: number;
    lng: number;
  };
}
// Ideal things we can do with the map in index.ts
export class CustomMap {
  // addMarker(mappable: User | Company): void {
  // Instead of maintaing list types, we can use the Mappable type
  addMarker(mappable: Mappable): void {}
}

Typescript does an implicit check of User and Company to make sure they pass as type Mappable

To help identify errors in classes we can use export:

// by adding export, we can use this to help with error checking in User
// and Company classees
export interface Mappable {}

And then add implements to the Class itself

import { Mappable } from './CustomMap';
// Since we export Mappable, we can use implements
// (not extends!) Mappable to help id errors
// Not required, but helpful :)
export class User implements Mappable {}

Now errors will show inside the User class showing expectations of Mappable

Typical Typescript file

Review of why this project used Parcel: “Parcel is a Web Application Bundler. It’s in the same tool category of webpack, with a different value proposition. Parcel promises to do many things without any configuration at all, and be fast too.”

R3 Day 98: 2020-06-26 Friday

Example of User.js that creates a user with faker data; uses the export keyword:

import faker from 'faker';

export class User {
  name: string;
  location: {
    lat: number;
    lng: number;
  };

  constructor() {
    // generate random info using faker
    this.name = faker.name.firstName();
    // this.location.lat -- this is undefined!
    this.location = {
      lat: parseFloat(faker.address.latitude()), // return a number to match definition above
      lng: parseFloat(faker.address.longitude())
    };
  }
}
import { User } from './User';
// anything we export something from a file, we use curly braces
// this allows us to export mulitple items with diff names
// different from `export default` as that will be the default
// export default is rarely used in TS
const user = new User();

Limit access to methods on third-party plugins:

// Instead of creating and calling this directly in index.ts, let's
// create a Map class to limit the functionality allowed in index.ts
const map = new google.maps.Map(document.getElementById('map'), {
  zoom: 2,
  center: {
    lat: 0,
    lng: 0
  }
});

R3 Day 97: 2020-06-25 Thursday

Constructors

// way 1
color: string;
// a constructor is instantly executed and uses arguments
constructor(color: string) {
  this.color = color; // if you use a constructor, then don't define it above
}
// end way 1

// way 2 -- add public, equivalent to way 1!
constructor(public color: string) { }
// end way 2

constructors that extend a parent class need super() calls

Going to use npm install -g parcel-bundler for packaging TS code going forward

R3 Day 96: 2020-06-24 Wednesday

Typescript Classes

// refer to as the Super Class
class Vehicle {
  drive(): void {
    console.log('chugga chugga');
  }
  honk(): void {
    console.log('beep');
  }
}
// refer to as the Child Class
class CarClass extends Vehicle {
  // copies all props from Vehicle
  // if we want to override, we can
  drive(): void {
    console.log('vroom');
  }
}
const carInstance = new CarClass();
carInstance.drive();
carInstance.honk();

Modifers: keywords we can place on methods and props inside a class

Notes:

R3 Day 95: 2020-06-23 Tuesday

Tuples:

const pepsiArray = ['brown', true, 40];
const pepsiTuple: [string, boolean, number] = ['brown', true, 40];

// Can also be done as a "type alias"
// not an array--> defines the tuple!
type Drink = [string, boolean, number];
const coke: Drink = ['brown', true, 39];
const tea: Drink = ['brown', false, 15];

Interfaces in Typescript

interface Vehicle {
  name: string;
  year: number;
  broken: boolean;
}
const listVehicle = (vehicle: Vehicle): void => {
  console.log(`Name: ${vehicle.name}`);
  console.log(`Year: ${vehicle.year}`);
  console.log(`Broken: ${vehicle.broken}`);
};

// Refactoring
// Q: But what happens to all the type checking for the vehicles?
// Q: Can we have optional, but defined, variables in the Interface?
interface Reportable {
  summary(): string;
}
const car1 = {
  prop1: 'vw',
  summary(): string {
    return `This ${this.prop1} is awesome.`;
  }
};
const printSummary = (item: Reportable): void => {
  console.log(item.summary());
};
printSummary(car1);

R3 Day 94: 2020-06-22 Monday

let numberAboveZero: boolean | number = false;

Destructured function example:

const logWeatherDestr = ({
  date,
  weather
}: {
  date: Date;
  weather: string;
}): void => {
  console.log(date, weather);
};

Object example:

const {
  coords: { lat, lng }
}: { coords: { lat: number; lng: number } } = profile;

R3 Day 93: 2020-06-21 Sunday

Typescript

What is it? Basically:

Typescript:

Resources:

FetchJSON app

Primitive types:

Object types: (we can tell TS to treat as a diff Object type)

Inferences vs. annotation

R3 Day 92: 2020-06-20 Saturday

Reviewing the setup of our first Microservices app and setup for next

Review upcoming ticket app

Data

Services

R3 Day 91: 2020-06-19 Friday

Microservices: Skaffold

Skaffold

R3 Day 90: 2020-06-18 Thursday

Exploring Deno with Bozeman JS group :)

R3 Day 89: 2020-06-17 Wednesday

Adding Ingress config:

Create ingress-srv.yaml and apply file

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-srv
  annotations: # helps ingress understand that we are sending it routing rules
    kubernetes.io/ingress.class: nginx
spec:
  rules: # all the routing rules to teach ingress how to route incoming traffic
    - host: posts.com # ingress assumes you may be hosting multiple domains
      http:
        paths:
          - path: /post # match what the posts/index.js expects traffic on
            backend:
              serviceName: posts-clusterip-srv # send requests to this service
              servicePort: 4000 # matches what is in posts-depl.yaml port

Ingress host

Getting React to work in cluster

Q: Issue with adding a post and refreshing; need to rebuild query service in order for new posts to show up?

R3 Day 88: 2020-06-16 Tuesday

Outside world -> Load Balancer -> Ingress Controller -> Cluster (Pod)

R3 Day 87: 2020-06-15 Monday

Integrating React portion

R3 Day 86: 2020-06-14 Sunday

Keyword Universe clusters

R3 Day 85: 2020-06-13 Saturday

Setting up Cluster IP service

Add cluster IP service to existing deployment file for each pod config to make it easier to manage incoming requests

How to Communicate between services

R3 Day 84: 2020-06-12 Friday

Setting up Cluster IP service

Will allow posts and event bus to talk to eachother

R3 Day 83: 2020-06-11 Thursday

Made a quick Go program for a GDG meetup with James Perkins!

madlibs/main.go

package main

import "fmt"

func main() {
	var exclamation string = ""
	var adverb string = ""
	var noun = ""
	var adjective string = ""

	fmt.Print("Enter a exclamation!")
	fmt.Scanln(&exclamation)
	fmt.Print("Enter an adverb!")
	fmt.Scanln(&adverb)
	fmt.Print("Enter a noun!")
	fmt.Scanln(&noun)
	fmt.Print("Enter an adjective!")
	fmt.Scanln(&adjective)

	fmt.Println(exclamation+"!", "She said", adverb, "as she jumped into her",
		adjective, noun, "and drove off with her", adjective, "dog.")
}

R3 Day 82: 2020-06-10 Wednesday

Updating deployments

Recommended method using Docker Hub (no need for hardcoded versions)

  1. The deployment must be using the ‘latest’ tag in the pod spec sections
  2. Make the updates to your code
  3. Build the image
  4. Push the image to docker hub: docker push satinflame/posts
  5. Run the command: kubectl rollout restart deployment [depl_name] (depl_name should refer to the deployment NAME when you view kubectl get deployments)

Services

K8s Services provide networking between pods

Types of services:

Creating a NodePort service in posts-srv.yaml:

apiVersion: v1
kind: Service
metadata:
  name: posts-srv
spec:
  type: NodePort
  selector:
    app: posts
  ports:
    - name: posts
      protocol: TCP
      port: 4000
      targetPort: 4000
k apply -f posts-srv.yaml
service/posts-srv created

k get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          2d19h
posts-srv    NodePort    10.102.129.168   <none>        4000:30595/TCP   19s

NodePort now available (30595) and you can access this endpoint at http://localhost:30595/posts

R3 Day 81: 2020-06-09 Tuesday

Understanding a Pod Spec

Common Kubectl Commands

Bash Alias

alias k="kubectl"
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

Deployments

posts-depl.yaml (No longer going to use posts.yaml for single pod)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: posts-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: posts
  template:
    metadata:
      labels:
        app: posts
    spec:
      containers:
        - name: posts
          image: satinflame/posts:0.0.1

Common Deployment Commands

R3 Day 80: 2020-06-08 Monday

Kubernetes

Kubernetes vocab:

Always use config files to create Objects–Deployments, Pods, and Services; do not type direct commands

Config

apiVersion: v1
kind: Pod
metadata:
  name: posts
spec:
  containers:
    - name: posts
      image: satinflame/posts:0.0.1

R3 Day 79: 2020-06-07 Sunday

Create Dockerfile for posts

Common commands:

Kubernetes is a tool for running many different containers

R3 Day 78: 2020-06-06 Saturday

Running Node.js in a Docker Container

Initial Attempt:

# base image
FROM alpine
# Install dependencies
RUN npm install
# Set start command
CMD [ "npm", "start" ]

docker build .

Possible errors:

Cleaning up working directory

Making changes to the local files

Our final, awesome Dockerfile:

# base image
FROM node:alpine
# Create work directory
# If not exists, this folder will be created
WORKDIR /usr/app
# Split COPY into two steps to avoid having to npm install each rebuild
COPY ./package.json ./
# Install dependencies
RUN npm install
# Copy local file system to container
# Move this after npm install so npm install doesn't need to be rerun
COPY ./ ./
# Set start command
CMD [ "npm", "start" ]

R3 Day 77: 2020-06-05 Friday

SEO reviewing common pitfalls

R3 Day 76: 2020-06-04 Thursday

Docker images

Tagging an image

R3 Day 75: 2020-06-03 Wednesday

Microservices: Basics of Docker

More about -it

Running a terminal inside your running container

Docker Images

Creating an Image:

# Use existing image (alpine) as base
FROM alpine

# Download and Install depedency
RUN apk add --update redis

# Tell image what to do with in starts as a container
CMD ["redis-server"]

FROM, RUN, CMD are docker commands used in the Dockerfile

R3 Day 74: 2020-06-02 Tuesday

Microservices: Basics of Docker

docker run <image name> command

Lifecycles

Seeing what was run:

Redis:

R3 Day 73: 2020-06-01 Monday

Playing with Jamdocs on Netlify, uses gridsome and Forestry: https://virtual-jamdocs.netlify.app/

R3 Day 72: 2020-05-31 Sunday

Microservices: Running services with Docker

Basics of Docker

R3 Day 71: 2020-05-30 Saturday

Storing events

Steps:

  1. Every time an event occurs we store it inside an array
  2. Add an endpoint to event bus that allows us to retrieve all the events that ever occurred

R3 Day 70: 2020-05-29 Friday

Microservices Query Service: Add moderation

Best practice: Query service only listens for update events:

R3 Day 69: 2020-05-28 Thursday

Beginning adding comment moderation to Udemy Microservices Blog feature

R3 Day 68: 2020-05-27 Wednesday

Added handlesbars for implementing conditional content in sendgrid email templates–hopefully can reduce the large amount of email templates down to a few!

R3 Day 67: 2020-05-26 Tuesday

Implement query service for listing posts and comments. GitHub changes

R3 Day 66: 2020-05-25 Monday

A little break from programming; working on SEO Gap analysis for my website and some complex Excel functions.

R3 Day 65: 2020-05-24 Sunday

Microservices blog

Current data flow:

Proposed: Asynchronous call using an Event bus

Emitting events

Notes:

R3 Day 64: 2020-05-23 Saturday

Playing with football APIs. ESPN seems to have a good–albeit undocumented–API.

Notes:

R3 Day 63: 2020-05-22 Friday

Microservices react components for (listing and adding) Posts and Comments complete.

R3 Day 62: 2020-05-21 Thursday

Inspired by Scott Mathson’s SEO on the Jamstack presentation - VirtuaCon (Jekyll) to add schema to a website using Hugo.

Notes:

R3 Day 61: 2020-05-20 Wednesday

Different ways to define a React component

You have to extend React.Component to create a stateful component which then will need a constructor and you’ll be able to use the state.

Create Component using Class

class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'Hello React'
    };
  }
  render() {
    return <div>{this.state.title}</div>;
  }
}

Implicit

export default function Foo(props) {
  return <div>My component</div>;
}

Using arrow functions

Using an arrow function with a class property ensures that the method is always invoked with the component as the value for this, meaning that the manual rebinding here is redundant:

this.handleUpdateInput = this.handleUpdateInput.bind (this);

export default (details) => {
  // code
};

or from Dan Abramov: “Arrows work just fine if you give them implicit name first.”

const RenderDetails = (details) => {
  // code
};
export default RenderDetails;

R3 Day 60: 2020-05-19 Tuesday

Determine React component hierarchy

Begin adding React components

R3 Day 59: 2020-05-18 Monday

R3 Day 58: 2020-05-17 Sunday

Section 2: A Mini-Microservices App

App steps

  1. Create a new app via create react app
  2. Create an express-based project for the posts service
  3. Create an express-based project for the comments service

R3 Day 57: 2020-05-16 Saturday

Microservices built with Node, React, Docker and Kubernetes

Communicating between services (not the same meaning as JavaScript)

R3 Day 56: 2020-05-15 Friday

Typed arrays are actually objects, and they don’t have access to array methods like push and pop. đŸ€·â€â™€ïž But they can help with performance by only allocating the memory space you need. Learning data structures from #freecodecamp! #womenintech #codenewbie R3D56/#100DaysOfCode

VSCode: Alt + Shift to edit multiple lines

FCC Data Structures

Type Each element size in bytes
Int8Array 1
Uint8Array 1
Uint8ClampedArray 1
Int16Array 2
Uint16Array 2
Int32Array 4
Uint32Array 4
Float32Array 4
Float64Array 8

Typed arrays do not have some of the methods traditional arrays have such as .pop() or .push(). Typed arrays are type object.

Last-In-First-Out using .push() and .pop()

R3 Day 55: 2020-05-14 Thursday

Working on mocking up my faux Knight University website using TailwindCSS. I’m finding maybe it’s best to componentize all the things (like buttons for example.) Maybe even headers (h2, h3)? Curious how others manage this. https://github.com/virtual/knightu R3D55/#100DaysOfCode

R3 Day 54: 2020-05-13 Wednesday

Set up my SSH config on my Mac so I don’t have to type crazy-long SSH lines! Logged into DigitalOcean to look into setting up a droplet to try out Docker, TDD & CI/CD and realized I still have no idea what I’m doing. https://www.ostechnix.com/how-to-create-ssh-alias-in-linux/ R3D54/#100DaysOfCode

R3 Day 53: 2020-05-12 Tuesday

A little DGD while I code an AMP example with GDG! Thanks for teaching the #AMPstudygroup benmorss! R3D53/#100DaysOfCode https://virtual-gdg-amp-study-group.glitch.me

Feeling motivated an inspired today. Morning yoga, Toastmasers, and an AMP workshop with GDG!

AMP Project: Cheesey Bikes

AMP Notes

Tell the browser your page is AMP using one of two ways:

<html amp ...>
  <html ⚡ ...></html>
</html>

Types implemented:

Required scripts have to go before the call to the element.

Extra:

Docker

Ports

? Maybe

R3 Day 52: 2020-05-11 Monday

Finished Learn Phaser: Physics from Codecademy; working on technical audit for SEO

R3 Day 51: 2020-05-10 Sunday

I’ve been continuing to play with bugs in Phaser.JS game tutorials and also working out SEO issues while going through Blue Array Academy’s course. (Good info–free through May.) R3D47-51/#100DaysOfCode

R3 Day 50: 2020-05-09 Saturday

Continuing Codecademy: Phaser.js Physics

SEO

R3 Day 49: 2020-05-08 Friday

Continuing Codecademy: Phaser.js Physics

SEO

What are the ideal lengths for meta?

R3 Day 48: 2020-05-07 Thursday

Continuing Codecademy: Phaser.js Physics

SEO

Questions

R3 Day 47: 2020-05-06 Wednesday

Continuing Codecademy: Phaser.js Physics

SEO

4 pillars:

SEO Roadmap document

For new sites, focus on content with low competition keywords

R3 Day 46: 2020-05-05 Tuesday

A little more fun with Phaser.js today; also trying it out on my own with a little Maplestory panda and some physics like bounce and gravity. R3D46/#100DaysOfCode https://cdpn.io/virtual/debug/QWjaRRo/ZoMBaznVqdEk

R3 Day 45: 2020-05-04 Monday

Finished the first section on learning Phaser.js for game development–managing state and taking input. I’m also pretty excited for the next section (it involves coloring a pegasus!) 🩄🎹 R3D45/#100DaysOfCode https://www.codecademy.com/courses/learn-phaser/lessons/learn-phaser-basics

Phaser.JS

SEO

R3 Day 44: 2020-05-03 Sunday

Today I’m learning the basics of Phaser.js for game development–including preload, create, and update functions. R3D44/#100DaysOfCode https://www.codecademy.com/learn/learn-phaser

Game Development with Phaser.JS

Phaser games are composed of Scenes that we define and pass to Phaser in the config! A Phaser Scene can have any of the following functions:

scene: {
  preload, create;
}

Note that we are using JavaScript’s property-value shorthand, the code above would be the same if we passed { preload: preload, create: create } to the scene instead.

R3 Day 43: 2020-05-02 Saturday

Worked a little more on my minecraft drawing tool, fixing the grid on load and touch on mobile; but mostly just watching Dance Gavin Dance music videos. R3D43/#100DaysOfCode

R3 Day 42: 2020-05-01 Friday

Ready for the weekend! Made a silly little Minecraft doodle tool with jQuery. Interesting challenge using mousedown / mousemove to keep drawing. Happy May Day! đŸŒŒ R3D42/#100DaysOfCode https://codepen.io/virtual/full/vYNeajo

R3 Day 41: 2020-04-30 Thursday

Learning about continuous integration with TravisCI and automatically building from GitHub to DockerHub. All interesting pieces–will be neat to figure this out with my own server! R3D41/#100DaysOfCode

Lynda Cert

Continuous integration

Other builds

R3 Day 40: 2020-04-29 Wednesday

Set up docker-compose files and now know a little more about running Docker containers. đŸ€— The VSCode Docker plugin is also helpful for seeing active containers and writing out Dockerfiles! (https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) https://www.lynda.com/Docker-tutorials/Leverage-power-Docker/2211315/2221492-4.html R3D40/#100DaysOfCode

đŸ›„ïž Bonus: Ahoy! Docker containers are named after shipping containers. More nautical analogies can be found in this article on demystifying Docker and Kubernetes. https://apifriends.com/api-management/docker-and-kubernetes/

Docker for Developers

Getting started

Develop with Docker

Fullstack–putting it together

R3 Day 39: 2020-04-28 Tuesday

Getting Started with Google Kubernetes Engine

Labs: Introduction to Containers and Docker

Introduction to Containers

History of servers

Introduction to Docker

IRL: you push and pull images from a registry

What are advantages of containers versus virtual machines?

Which types of actions can you perform in a container Dockerfile?

What is the default hostname to publish a Docker image to the Google Registry?

Clusters, Nodes, and Pods

Kubernetes – an open-source orchestrator for a container environment, it manages and delegates jobs

Services, Labels, and Selectors

Volumes

Why use Kubernetes (i.e. what benefit does it provide to containers?)

What does a pod specify?

Which component do you use to send requests to API servers on masters to configure the cluster?

Deployments and Rolling Updates

Canary and Blue-Green Deployments

Lab: Deploying to Kubernetes

What is the purpose of the ReplicaSet?

When are rolling deployments triggered?

How does Kubernetes choose instances in the second deployment of a canary deployment?

Creating a Continuous Delivery Pipeline

Deploying a continuous delivery pipeline enables you to build, stage, test, and deploy your application, using automated triggers and manual approvals. (e.g. Spinnaker or Jenkins)

Why is it useful to set up continuous delivery with Kubernetes?

Which 3 deployments are used in our instance of Kubernetes continuous delivery?

Which of the following best describes why we used Jenkins for continous delivery with Kubernetes?

R3 Day 38: 2020-04-27 Monday

Finished the second infosec challenge for #freecodecamp! I learned a lot about returning statuses, errors, and messages from the API and more types of assertions with #ChaiJS. R3D38/#100DaysOfCode https://glitch.com/~virtual-fcc-issue-tracker

------------------------|---------|----------|---------|---------|---------------------------------------------------------------------------
File                    | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------------|---------|----------|---------|---------|---------------------------------------------------------------------------
All files               |   43.84 |    42.11 |   30.77 |   47.83 |
 app                    |   23.23 |     3.13 |       0 |   26.74 |
  assertion-analyser.js |    1.54 |        0 |       0 |    1.92 | 31-128
  server.js             |   64.71 |       25 |       0 |   64.71 | 26,32,43,52-61
 app/controllers        |   57.14 |    57.69 |   44.44 |   57.14 |
  dataHandler.js        |   57.14 |    57.69 |   44.44 |   57.14 | 16-17,20-21,24-25,28-29,32-33,47,50,54,57,60
 app/routes             |   54.93 |    51.06 |   41.38 |   59.09 |
  api.js                |   76.67 |    65.75 |     100 |   77.53 | 27,74,77,83,86,89,105-110,159,191,198,208,211,214,217,220-222,232,265,278
  fcctesting.js         |   17.31 |        0 |    5.56 |   20.93 | 38-41,46-49,54-57,63-73,77-102
------------------------|---------|----------|---------|---------|---------------------------------------------------------------------------

R3 Day 37: 2020-04-26 Sunday

Oof.

¯_(ツ)_/¯ 3 hours on deconstructing a boolean to send in a MongoDB query. Still no idea. https://glitch.com/edit/#!/virtual-fcc-issue-tracker?path=routes/api.js:128:22 R3D37/#100DaysOfCode

R3 Day 36: 2020-04-25 Saturday

Reviewing HTTP response statuses sent in APIs. It seems that there’s not even agreement over the correct status for GET for an element that does not exist in DB (404/204/null object/500?), but I now have plenty of references! R3D36/#100DaysOfCode https://nordicapis.com/best-practices-api-error-handling

Example of 404 response:

// GET (BY ID)
app.get('/api/tasks/:id', (request, response) => {
  const taskId = request.params.id;
  const task = tasks.find((task) => task.id === parseInt(taskId));
  if (!task)
    return response
      .status(404)
      .send('The task with the provided ID does not exist.');
  response.send(task);
});

Recommended example (ref RFC 7807) from Best Practices for REST API Error Handling:

This schema is composed of five parts:

  1. type — A URI identifier that categorizes the error
  2. title — A brief, human-readable message about the error
  3. status — The HTTP response code (optional)
  4. detail — A human-readable explanation of the error
  5. instance — A URI that identifies the specific occurrence of the error
{
  "type": "/errors/incorrect-user-pass",
  "title": "Incorrect username or password.",
  "status": 403,
  "detail": "Authentication failed due to incorrect username or password.",
  "instance": "/login/log/abc123"
}

For example, in HTML, a problem could be embedded by encapsulating JSON in a script tag (pg 16):

<script type="application/problem+json">
  {
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
                "/account/67890"]
  }
</script>

Example from twitter API:

{
  "errors": [
    {
      "message": "Sorry, that page does not exist",
      "code": 34
    }
  ]
}

Example from facebook API:

{
  "error": {
    "message": "An active access token must be used to query information about the current user.",
    "type": "OAuthException",
    "code": 2500,
    "fbtrace_id": "A6S6sVDcfVJd7p7vcOABR0d"
  }
}

Example from Twilio API:

{
  "code": 21211,
  "message": "The 'To' number 5551234567 is not a valid phone number.",
  "more_info": "https://www.twilio.com/docs/errors/21211",
  "status": 400
}

Questions

R3 Day 35: 2020-04-24 Friday

Back to #freecodecamp’s 2nd InfoSec challenge–I’m still not understanding how best to write functional tests. It appears that I need to learn more about returning error statuses from the API. (Any recommendations on related reading?) đŸ€” R3D35/#100DaysOfCode #chaijs

Add coverage to FCC Issue Tracker Glitch project:

------------------------|---------|----------|---------|---------|--------------------------------
File                    | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------------|---------|----------|---------|---------|--------------------------------
All files               |   29.29 |     4.85 |      24 |   32.41 |
 app                    |   23.23 |     3.13 |       0 |   26.74 |
  assertion-analyser.js |    1.54 |        0 |       0 |    1.92 | 31-128
  server.js             |   64.71 |       25 |       0 |   64.71 | 26,32,43,52-61
 app/controllers        |   51.72 |        0 |   71.43 |   51.72 |
  dataHandler.js        |   51.72 |        0 |   71.43 |   51.72 | 36-40,43-65
 app/routes             |   28.83 |     7.84 |   24.14 |   31.68 |
  api.js                |   38.98 |    13.33 |   54.55 |   39.66 | 27,88,133,147-255
  fcctesting.js         |   17.31 |        0 |    5.56 |   20.93 | 38-41,46-49,54-57,63-73,77-102
------------------------|---------|----------|---------|---------|--------------------------------

FCC Issue Tracker Reference

R3 Day 34: 2020-04-23 Thursday

Digging into CSS & JS SourceMaps; add “.sourceMaps()” to webpack mix.

I’ll be adding these into my clients’ websites as I work on them—an easier method to debug code without needing to ship an unminified version to production! R3D34/#100DaysOfCode https://css-tricks.com/should-i-use-source-maps-in-production/

Add sourceMaps() to webpack.mix.js:

  mix.js('source/_assets/js/main.js', 'js')
    .sourceMaps(productionToo = true,
      type = 'eval-source-map')
    ...

R3 Day 33: 2020-04-22 Wednesday

Checkbox ranges using Shift! And now that I know how to incorporate them, I’ll need to make sure more of my projects use them.

☑ Challenge 10/#javascript30 R3D33/#100DaysOfCode https://virtual-javascript30.herokuapp.com/

R3 Day 32: 2020-04-21 Tuesday

After learning more about ESLinting, I added similar functionality for .scss to a project using stylelint! Lots of information and plugins out there, but I’d love to see examples of your .stylelintrc files too if you use it. R3D32/#100DaysOfCode https://github.com/stylelint/awesome-stylelint

One of my goals for incorporating style linting is to be better at arranging my properties in a coherent manner.

“If you can always count on certain properties being in the same place, you can understand the CSS a bit faster (less scanning).” https://css-tricks.com/poll-results-how-do-you-order-your-css-properties/

WIP Stylelinting

"stylelint": "^13.3.3",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-declaration-block-no-ignored-properties": "^2.3.0",
"stylelint-order": "^4.0.0",

Stylelint tips:

Glad you’re learning to use stylelint! The 50+ rules that limit language features are often overlooked. They are *-pattern, *-blacklist, *-whitelist and *-max-* rules that you can use to enforce non-stylistic conventions in your CSS.

{
  "declaration-no-important": true,
  "media-feature-name-whitelist": ["min-width"],
  "selector-class-pattern": "^[a-z][a-zA-Z0-9]+$",
  "selector-max-id": 0,
  "unit-whitelist": ["rem"]
}

To enforce rem units, min-width media queries, camelCase selectors and so on.

R3 Day 31: 2020-04-20 Monday

Been putting this off since January—updated my webserver to the next OS version.

Killed off MariaDB on recommended purge/cleanup, but thankfully when I reinstalled it, all my databases were still there. Small miracles. 🌟 R3D31/#100DaysOfCode

IBM Practitioner

Restless reinvention

Include a variety of voices

Planning

R3 Day 30: 2020-04-19 Sunday

Spent the day learning https://istanbul.js.org/ and code coverage. What is it? The measure (%) of how much code is executed with a given operation. (Goal: 100% coverage!) R3D30/#100DaysOfCode

  • Executed statements
  • Branches
  • Called, defined functions
  • Executed lines

đŸŽ” Bonus: why do you run the Istanbul test coverage library with nyc instead of istanbul? It’s a reference to the song “Istanbul (not Constantinople)” from They Might Be Giants! https://www.youtube.com/watch?v=xo0X77OBJUg

What is code coverage?

Statements–perform an action in code

Branches–each statement within a conditional

if (condition) {
  statement1(); //branch 1
} else {
  statement2(); //branch 2
  statement3(); //branch 2
}

Function–a function that is never called

Line–a line that is never executed

How do we implement code coverage?

Code coverage libraries:

Install:

Functional Testing

Example user stories for Functional Testing:

As a user, I want to:

Installing Chai HTTP: npm install chai-http -D

Chai docs on using .get(), end

Because the end function is passed a callback, assertions are run asynchronously. Therefore, a mechanism must be used to notify the testing framework that the callback has completed. Otherwise, the test will pass before the assertions are checked.

For example, in the Mocha test framework, this is accomplished using the done callback, which signal that the callback has completed, and the assertions can be verified:

it('fails, as expected', function (done) {
  // <= Pass in done callback
  chai
    .request('http://localhost:8080')
    .get('/')
    .end(function (err, res) {
      expect(res).to.have.status(123);
      done(); // <= Call done to signal callback end
    });
});

it('succeeds silently!', function () {
  // <= No done callback
  chai
    .request('http://localhost:8080')
    .get('/')
    .end(function (err, res) {
      expect(res).to.have.status(123); // <= Test completes before this runs
    });
});

When done is passed in, Mocha will wait until the call to done(), or until the timeout expires. done also accepts an error parameter when signaling completion.

Need to parse HTML to check for valid output? Check out cheerio.js

“100% Test” coverage:

Open source continuous integration:

Continuous Integration as a Service:

CI Features to look for:

Establishing Code Standards

Mine are here: https://satinflame.com/uses

Brad Traversy

R3 Day 29: 2020-04-18 Saturday

Learning how to test code and watch if it successfully creates entries & which actions are performed. Test doubles, stubs, spies & mocks. Not understanding everything
 but more info can also be found in this 800+ page book! http://xunitpatterns.com 🙈 R3D29/#100DaysOfCode

Overriding dependencies

Process of Stubbing a Custom Response

Example: testing a module that updates the database:

Observing interactions with Spies

Sinon Mocks

Book ref: xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros

R3 Day 28: 2020-04-17 Friday

Back to more testing with Mocha and Chai. Set up example tests for unit tests, callbacks and promises. Mocha doesn’t use arrow functions in order to keep the correct binding for this. R3D28/#100DaysOfCode https://www.lynda.com/Node-js-tutorials/Node-js-Testing-Code-Quality/587672-2.html

describe('Reservation Suite', function () {
  context('Date and Time Combination', function () {
    it('should return a ISO 8601 date and time with valid input', function () {
      const date = '2020/04/17';
      const time = '04:53 PM';

      Reservation.combineDateTime(date, time).should.equal(
        '2020-04-17T16:53:00.000Z'
      );
    });
  });
});

R3 Day 27: 2020-04-16 Thursday

Code things that make you happy! 😄

Saw examples of snaking timelines from #smashingconf and haven’t stopped thinking about them since! Snake

Haml, CSS, and JS for reordering cards in the responsive design. R3D27/#100DaysOfCode #WomenWhoCode https://codepen.io/virtual/pen/bGVpdyN

IBM Design thinking

Notes

R3 Day 26: 2020-04-15 Wednesday

Today I customized ESLint to keep code tidy and standardized within a project.

You can also customize your own config and add it to npm for others to use as a dependency—as Google and Airbnb have done for their teams. Neat! R3D26/#100DaysOfCode https://medium.com/@natterstefan/how-to-create-your-own-shared-eslint-prettier-and-stylelint-configuration-3930dd764de3

Validate correctness using Unit Testing

Node.js Testing frameworks:

Assertion Libraries (that work with any testing framework):

Installing

module.exports = {
  env: {
    mocha: true
  },
  rules: {
    'no-unused-vars': ['error', { varsIgnorePattern: 'should|expect' }]
  }
};

ESLint Configs

R3 Day 25: 2020-04-14 Tuesday

Learning how to set up and configure EditorConfig and ESLint in order to maintain consistent coding standards in my projects! R3D25/#100DaysOfCode https://www.lynda.com/Node-js-tutorials/Node-js-Testing-Code-Quality/587672-2.html

Linter:

ESLint

R3 Day 24: 2020-04-13 Monday

Following along on a @lynda course from @FluxSauce on Node.js testing. Great info on testing libraries vs. assertion libraries, TDD vs. BDD, and soon will be digging into setting up better linting tools! R3D24/#100DaysOfCode https://www.lynda.com/Node-js-tutorials/Node-js-Testing-Code-Quality/587672-2.html

Node.js: Testing and Code Quality - Jon Peck

Different types of testing:

TDD vs BDD

R3 Day 23: 2020-04-12 Sunday

Happy Easter! đŸŒŒ Taking a step back from freeCodeCamp projects to learn JavaScript testing a bit more thoroughly on Lynda. Are there any recommendations for good walkthroughs on TDD/BDD (Test/Behavior-Driven Development) using Node.js/ChaiJS? R3D23/#100DaysOfCode

Reviewing Testing

Node.js: Testing and Code Quality - Jon Peck

Notes:

TDD General Notes:

Five steps to TDD (also known as Red-Green-Refactoring):

  1. Read, understand, and process the feature or bug request.
  2. Translate the requirement by writing a unit test. If you have hot reloading set up, the unit test will run and fail as no code is implemented yet.
  3. Write and implement the code that fulfills the requirement. Run all tests and they should pass, if not repeat this step.
  4. Clean up your code by refactoring.
  5. Rinse, lather and repeat.

Questions:

R3 Day 22: 2020-04-11 Saturday

R3D22/#100DaysOfCode Working out how to use expect functions in addition to assert in Chai, but the doc’s examples aren’t even working in my app. Need to check version support.

Slow going with adding testing to the 2nd infosec challenge for #freecodecamp.

Questions:

IBM Design thinking

Notes

R3 Day 21: 2020-04-10 Friday

CRUD Working! Post, Get, Put, and Delete routes for #freecodecamp’s 2nd infosec project now setup.

Next to figure out is the testing and learn what I really set up incorrectly. 😆 R3D21/#100DaysOfCode https://virtual-fcc-issue-tracker.glitch.me/apitest/

Questions:

db.collection("issues").update(
  { _id: ObjectId(issueID) },
  { $set: projectObj },
  function(err, result) {
    ...

R3 Day 20: 2020-04-09 Thursday

Today I created the delete route for #freecodecamp’s 2nd Infosec project.

Added a check to see if the ID actually exists prior to deleting it. Using findOne() seems to be better as you don’t need to parse an array. R3D20/#100DaysOfCode https://virtual-fcc-issue-tracker.glitch.me/apitest/

Questions:

R3 Day 19: 2020-04-08 Wednesday

Spent another day digging into MongoDB for #freecodecamp’s 2nd Security project. Updated my post route to use real form input and worked out the response for the get route as well.

Half of the CRUD is working now! 😋 https://virtual-fcc-issue-tracker.glitch.me/apitest/ R3D19/#100DaysOfCode

Questions:

Started IBM’s Design Thinking Practitioner Course

R3 Day 18: 2020-04-07 Tuesday

Started on the second security challenge for @freeCodeCamp, beginning with a bit of CRUD!

I’m really rusty on MongoDB, but I finally got my database connection set up and a fake object for Project Mew inserted in a collection! 🎉 R3D18/#100DaysOfCode

Glitch Project

Questions:

R3 Day 17: 2020-04-06 Monday

✅ Metric-Imperial Converter completed for @freecodecamp!

đŸ”č Built out controller functions
đŸ”č Verified correct return types
đŸ”č Added HelmetJS for security
đŸ”č Created unit and functional tests
đŸ”č Wrote API routes

https://virtual-fcc-mi-convert.glitch.me R3D17/#100DaysOfCode #womenintech

R3 Day 16: 2020-04-05 Sunday

Finished the unit tests for @freecodecamp’s M/I converter challenge. Tomorrow: functional tests!

I learned that Chai’s approximately only works if you actually return numbers—I will need to pay attention to my return types! R3D16/#100DaysOfCode

Enjoy your weekend!

R3 Day 15: 2020-04-04 Saturday

Building the first project for @freecodecamp’s security challenges. Added controller functions to process input (32mi) and calc output (51.5kg). @getpostman helps to debug. Love these projects, they really make things click! R3D15/#100DaysOfCode https://virtual-fcc-mi-convert.glitch.me

“Controllers” — functions that separate out the code to route requests from the code that actually processes requests.

Since I always forget the MVC setup:

R3 Day 14: 2020-04-03 Friday

R3D14/#100DaysOfCode Started working out the first @freeCodeCamp security challenge for a Metric-Imperial Converter. Reviewing how to use regex to split strings and integrate HelmetJS for security.

Glitch project

R3 Day 13: 2020-04-02 Thursday

Continuing @freecodecamp’s passport authentication and trying to debug errors preventing tests to pass even though it works. Frustrating! 😣

I hope all your coding adventures have been more rewarding today! R3D13/#100DaysOfCode

There are so many issues and gotchas with this chapter outlined in a myriad of forum posts and GitHub issues.

Time for me to leave this challenge and hope when I get back to it, it’s been given some TLC. I tried a GitHub PR for the page title issues, but it was rejected.

R3 Day 12: 2020-04-01 Wednesday

Just like any time I do server setup, spending way too much time debugging silly things like page titles


Is there anyone with @freecodecamp approval access that can review the PRs for this repo? R3D12/#100DaysOfCode https://github.com/freeCodeCamp/boilerplate-advancednode/pulls

Glitch project

Serialization of a User Object

To serialize an object means to convert its contents into a small key essentially that can then be deserialized into the original object. This is what allows us to know whos communicated with the server without having to send the authentication data like username and password at each request for a new page.

Authentication Strategies

A strategy is a way of authenticating a user.

R3 Day 11: 2020-03-31 Tuesday

Markdown links—someone once shared that “Brackets” comes before “Parenthesis” alphabetically, and I haven’t screwed up creating a link since! 💙 (Thank you!)

Working on @freeCodeCamp’s Node & Express section, starting with đŸ¶ #PugJS templates. R3D11/#100DaysOfCode

Pug code example:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5)
  body
    h1 Pug - node template engine
    #container.col
      if youAreUsingPug
        p You are amazing
      else
        p Get on it!
      p.
        Pug is a terse and simple templating language with a
        strong focus on performance and powerful features.

Passport

It’s time to set up Passport so we can finally start allowing a user to register or login to an account! In addition to Passport, we will use Express-session to handle sessions. Using this middleware saves the session id as a cookie in the client and allows us to access the session data using that id on the server. This way we keep personal account information out of the cookie used by the client to verify to our server they are authenticated and just keep the key to access the data stored on the server.

const session = require('express-session');
const passport = require('passport');

// ...

app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true
  })
);

// passport. initialize() is a middle-ware that initialises Passport. Middlewares are functions that have access to the request object (req), the response object (res), and the next middleware function in the application's request-response cycle
app.use(passport.initialize());

// passport.session() acts as a middleware to alter the req object and change the 'user' value that is currently the session id (from the client cookie) into the true deserialized user object.
// `app.use(passport.session());` is equivalent to `app.use(passport.authenticate('session'));`
app.use(passport.session());

R3 Day 10: 2020-03-30 Monday

Making R3D10/#100DaysOfCode an easier day, reading through the history of languages on Code Complete.

Amused by this tidbit: “The acronym PHP originally stood for Personal Home Page.”

Language History from Code Complete (ed.2, pp 63-66)

LL = Low-level ML = Mid-level HL = High-level OOL = Object-oriented

R3 Day 9: 2020-03-29 Sunday

Another #javascript30 down! Neat console logging ideas like formatting as errors, custom styles & grouping. Added @prismjs for syntax highlights.

I return for the intro riff đŸŽ¶ & stay for the great content from Wes Bos. 😉
https://virtual-javascript30.herokuapp.com/09-dev-tools/index.html R3D9/#100DaysOfCode

R3 Day 8: 2020-03-28 Saturday

R3D8/#100DaysOfCode Completed #Helmetjs/bcrypt for @freeCodeCamp’s Information Security and QA section.

Have any of you finished this certification? Thinking face I’m curious about what the projects are like and would love to see your GitHub repos/examples! #womenintech

Applied InfoSec Challenges

HelmetJS

HelmetJS is a type of middleware for Express-based applications that automatically sets HTTP headers to prevent sensitive information from unintentionally being passed between the server and client. While HelmetJS does not account for all situations, it does include support for common ones like Content Security Policy, XSS Filtering, and HTTP Strict Transport Security, among others. HelmetJS can be installed on an Express project from npm, after which each layer of protection can be configured to best fit the project.

Resources

BCrypt

BCrypt hashes are very secure. A hash is basically a fingerprint of the original data- always unique. This is accomplished by feeding the original data into an algorithm and returning a fixed length result. To further complicate this process and make it more secure, you can also salt your hash. Salting your hash involves adding random data to the original data before the hashing process which makes it even harder to crack the hash.

BCrypt hashes will always looks like $2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm which does have a structure. The first small bit of data $2a is defining what kind of hash algorithm was used. The next portion $13 defines the cost. Cost is about how much power it takes to compute the hash. It is on a logarithmic scale of 2^cost and determines how many times the data is put through the hashing algorithm. For example, at a cost of 10 you are able to hash 10 passwords a second on an average computer, however at a cost of 15 it takes 3 seconds per hash
 and to take it further, at a cost of 31 it would takes multiple days to complete a hash. A cost of 12 is considered very secure at this time. The last portion of your hash $ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm, looks like one large string of numbers, periods, and letters but it is actually two separate pieces of information. The first 22 characters is the salt in plain text, and the rest is the hashed password!

R3 Day 7: 2020-03-27 Friday

Finished Unit and Functional testing for @freecodecamp.

I was always curious about how to test an actual form. #ChaiJS can mimic filling in a form & submitting it, and test the output on the screen.

Assertions cheat sheet: https://devhints.io/chai R3D7/#100DaysOfCode

Chai Testing Repo running on Heroku

suite('Functional Tests', function () {
  test('submit "surname" : "Vespucci" - write your e2e test...', function (done) {
    browser
      // fill the form, and submit.
      .fill('surname', 'Vespucci')
      .pressButton('submit', function () {
        // assert that status is OK 200
        browser.assert.success(); // 200
        // assert that the text inside the element 'span#name' is 'Amerigo'
        browser.assert.text('span#name', 'Amerigo', 'name should be Amerigo');
        // assert that the text inside the element 'span#surname' is 'Vespucci'
        browser.assert.text('span#surname', 'Vespucci', 'surname is Vespucci');
        // assert that the element(s) 'span#dates' exist and their count is 1
        browser.assert.element('span#dates', 1, 'dates element exists');
        // assert.fail();
      });
    done();
  });
});

R3 Day 6: 2020-03-26 Thursday

R3D6/#100DaysOfCode Another day working with Chai on @freeCodeCamp. I’m impressed with the flexibility of tests like “approximately.”

Spent a while debugging my testing scripts until I realized I had the wrong branch set to be automatically deployed on Heroku–oops! 🙄

R3 Day 5: 2020-03-25 Wednesday

Happy to now be a monthly supporter for @freeCodeCamp!

R3D5/#100DaysOfCode Started working through the testing curriculum; worked out how to manage via GitHub and Heroku (instead of Glitch) so my workflow is much happier. đŸ€— https://github.com/virtual/boilerplate-mochachai

Chai Testing Repo running on Heroku

Note on CSS Update for reduced motion:

@​media (prefers-reduced-motion: reduce) {
  *,
  *:after,
  *:before {
    animation: none !important;
    transition: none !important;
  }
}

R3 Day 4: 2020-03-24 Tuesday

R3D4/#100DaysOfCode In-range but still invalid? Here’s a pen to help you understand the difference between :invalid and :out-of-range CSS psuedo-selectors. Example from @FrontendMasters CSS In-Depth. https://codepen.io/virtual/pen/abORwjw?editors=0100

Psuedo-selectors

Selectors that match based on the current state of the UI

:valid

:invalid (out of range and/or unmatched step value)

:required

:optional

:in-range

:out-of-range (out of range, ignores step)

:user-invalid Similar to on blur

R3 Day 3: 2020-03-23 Monday

R3D3/#100DaysOfCode I’ll admit, I don’t use these much (aside from form styling), and many have been around since CSS2! Do you ever style your elements this way?

Reviewing selectors, specificity, and gotchas with @estelle —you know, for the next CSS trivia night. Winking face

Selectors

Selector: “The part that comes before the declaration block”

Pseudo-classes have the same selector weight as classes (0 - 1 - 0)

Attribute selectors

[attribute] Has the attribute (e.g. [type])

[attribute='value'] Equal to the exact value only

[attribute~='value'] Includes the full word ‘value’

[attribute|='en'] Equal to “en” specifically or “en-“ followed by anything

[attribute^='val'] Starts with (e.g. ‘https:’)

[attribute$='lue'] Ends with (e.g. “.pdf”)

[attribute*='alu'] Has anywhere

R3 Day 2: 2020-03-22 Sunday

Interesting information on CSS failures and faux-commenting while you’re testing code as shown from CSS in Depth (v3) with @estelle, @FrontendMasters.

If you style CSS, take a peek at all these less common selectors! https://drafts.csswg.org/selectors-4/#overview R3D2/#100DaysOfCode

Began CSS In-Depth, v3, Estelle Weyl (FEM)

R3 Day 1: 2020-03-21 Saturday

Scrubbed my toaster, cleaned my knife set, cut my finger, and then decided maybe I should start #100daysofcode back up instead.

Challenge 8/#javascript30–now enjoying this mindnumbingly fun canvas board I can now doodle on like it’s 2002. R3D1 https://virtual-javascript30.herokuapp.com/08-canvas/index.html

Starting Round 3 of #100DaysOfCode–honestly for a mental health break from reading #covid19 info; getting back into Javascript30


⭐ ⭐ Round 3 begins ⭐ ⭐

Ideas tabled for later (see R3 Day 100 for projects worked on!)