Coder Social home page Coder Social logo

david-learns's Introduction

Hi there ๐Ÿ‘‹

Currently atlassian.com - ex takemybed.com, ex telstra.com, ex gridcog.com, ex spacetoco.com, ex genvis.co, ex codersforcauses.org, ex worley.com

10 years in the game

noobling profile

david-learns's People

Contributors

noobling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

david-learns's Issues

React best practices

Functional programming

Should aim to make each stateless functional component a pure function. They should take in props and return a DOM element without causing side effects

Functional components

If you need to have a this scope or encapsulate functionality then you can't use functional components.

Adding JSX in a codepen

Add babel 5.8 newer babels will not work as an in browser transformer.
Example here

Mounting Life cycle

ES6 class React.createClass()
' ' getDefaultProps()
constructorProps() getInitialState()
componentWillMount() componentWillMount()
render() render()
componentDidMount() componentDidMount()
componentWillUnmount() componentWillUnmount()

componentDidMount() runs code after the DOM has loaded which makes it a good place for third party JS code

Updating lifecycle

The updating lifecycle is a series of methods which are invoked when the state changes or new props are received from the parent component. e.g. updating lifecycle is invoked every time setState is called if you call setState within the updating lifecycle an infinite loop occurs.

componentWillReceiveProps(nextProps)

This is invoked when component receives new props this the only method for updating lifecycle where setState can be called`

shouldComponentUpdate(nextProps, nextState)

This can call off the updating to allow only necessary updates to improve performance

componentWillUpdate(nextProps, nextState)

Invoked just before the component updates

componentDidUpdate(nextProps, nextState)

Invoked after to component has been called with the render function

Solving the issue child not updating when props change from parent

https://codesandbox.io/s/6lnvzkky13

Higher Order React Components

Components that return other components
Examples here: https://codesandbox.io/s/n5jk4qmwp4

Tips

  • Store constants in a separate file and import them. Prevents typos creating cryptic errors
  • Name or exported functions helps with debugging

Redux

Reducers should be predictable. Generating random data, calling APIs and other asynchronous processes should be done outside of reducers.

David Learns JSON

Helpful JSON tools

https://next.json-generator.com/
https://jsoneditoronline.org
https://github.com/typicode/json-server (Fully featured fake api server)
https://jsonschema.net/

The purpose of toJSON

user = {
  firstName: 'David',
  lastName: 'Yu'
  get fullName() {
    return this.firstName + this.lastName
  },
  toJSON: function () {
    return {
      firstName: this.firstName,
      lastName: this.lastName
    }
  }
}

JSON.stringify(user) // => {"firstName":"David", "lastName":"Yu"}

We can see the user of toJSON where we want to exclude the fullName Attribute if called without toJSON in this case we get `{"firstName": "David", "lastName": "Yu", "fullName": "DavidYu"}

eval()

This will execute any serialised JS code

React

Composition

Containment

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color>
       {props.children}
    </div>
  )
}

Context

Used when some data needs to be accessed by many components at different nesting levels. Apply it sparingly because it makes component reuse more difficult. Examples include authenticated user, theme, preferred language

The issue of passing unused props to intermediate components in order to pass it down to a lower level component

Instead of this

<Page user={user} avatarSize={avatarSize} />
// ... which renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... which renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... which renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>

We can pass an entire component

function Page(props) {
  const user = props.user;
  const userLink = (
    <Link href={user.permalink}>
      <Avatar user={user} size={props.avatarSize} />
    </Link>
  );
  return <PageLayout userLink={userLink} />;
}

// Now, we have:
<Page user={user} avatarSize={avatarSize} />
// ... which renders ...
<PageLayout userLink={...} />
// ... which renders ...
<NavigationBar userLink={...} />
// ... which renders ...
{props.userLink}

Which means we only pass one prop rather than two.

The issue with this is that we are moving complexity higher up the tree making them more complicated and forces lower-level components to be more flexible than you want.

How to use Context

Basically global state

const MyContext = React.createContext(defaultvalue)

<MyContext.Provider value={}>
...
</MyContext.Provider>

class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of MyContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of MyContext */
  }
}
MyClass.contextType = MyContext;

Comp sci fundamentals

Stack and heap

Stack is first in last out like stacking plates on top of each other. This means it is faster to access data in this memory region because the items are of known size and you don't have to search. In contrast the heap stores items of unknown size at compile time. A pointer reference is used to locate the stored data in the heap so it is slower to access data.

Stack

  • LIFO pushing on the stack, popping off stack
  • Data takes up a known fixed size
  • Place to get data is always at the top
  • Data access is fast

Heap

  • Data with size unknown at compile time or size that might change can be stored on the heap
  • Less organised
  • OS finds empty spot to fit the data and returns a pointer (allocating on the heap)
  • Data is further apart
  • Data access is slower

Functional Programming

Functional trend came from lambda calculus. Functions have since been a part of calculus since it emerged in the 17th century. More complex functions are called higher-order functions.

In 1950s, John McCarthy took concepts from lambda calculus and applied them to a new programming language called Lisp. Lisp implemented the concept of higher-order functions and functions as first-class members or first-class citizens. A function is said to be a first-class citizen when it can be declared as a variable and sent to functions as an argument. These functions can be returned from functions.

Functional programs prefer recursion over loops because they have to since they cannot alter the state and have no side effects. Not having side effects means you cannot have loop counters since they constitute a mutable state. In recursion no state is needed so this is a natural match for recursion. Having no side effects also means that the compiler can optimise it better with tail call optimisation.

Higher-order functions

When a function returns or takes in other functions it is said to be a higher-order function

var createScream = function(logger) { 
            return function(message) {
            logger(message.toUpperCase() + "!!!")
        }
}

const scream = createScream(message => console.log(message))
scream('functions can be returned from other functions')
scream('createScream returns a function')
scream('scream invokes that returned function')
// FUNCTIONS CAN BE RETURNED FROM OTHER FUNCTIONS!!!
// CREATESCREAM RETURNS A FUNCTION!!!
// SCREAM INVOKES THAT RETURNED FUNCTION!!!

We can write it with arrow function as well.

createScream = logger => message => logger(message.toUpperCase() + "!!!")

Declarative vs Imperative programming

Functional programming is part of a larger programming paradigm called declarative programming.

Declarative programming focuses on what is supposed to happen whereas imperative programming focuses on how the task is achieved e.g. Implementation level.

///////////////// Imperative
var string = "This is the midday show with Cheryl Waters"; 
var urlFriendly = "";
for (var i=0; i<string.length; i++) { 
  if (string[i] === " ") {
    urlFriendly += "-"; 
  } else {
    urlFriendly += string[i];
  }
}
console.log(urlFriendly);

///////////////// Declarative
const urlFriendly = string.replace(/ /g, '-')

We can see declarative is higher level compared to imperative.

Immutability

Data is immutable in functional/declarative programming

let color_lawn = { 
  title: "lawn",
  color: "#00FF00",
  rating: 0 
}

////////////// Mutating the object
function rateColor(color, rating) { color.rating = rating
  return color
}
console.log(rateColor(color_lawn, 5).rating)
console.log(color_lawn.rating)

///////////// Functional Programming not mutating object

var rateColor = function(color, rating) {
  return Object.assign({}, color, {rating:rating})
}
console.log(rateColor(color_lawn, 5).rating) // 5
console.log(color_lawn.rating) // 4

///////////// No mutating using latest JS
const rateColor = (color, rating) => ({...color, rating})

//////////// Use functions that don't mutate data for example Array.push mutates use Array.concat or spread operator

Pure Functions

Pure functions Return a value based on the parameter passed in. They do not change the application state e.g. no side effects, set global variables. The advantage of these sort of functions are that they are easily testable and don't require a complicated setup. The output is also easier to predict. In React UI is expressed with pure functions e.g. const header = (props) => <h1>{props.title}</h1>

Most useful functions in JS (imo)

  • map
  • filter
  • join
  • reduce (Reduce array to a single value using some condition)

More examples of writing pure functions

//////////// Editing a certain value without altering original object
let schools = [
{ name: "Yorktown"},
{ name: "Stratford" },
{ name: "Washington & Lee"}, { name: "Wakefield"}
]

const editNames = (oldName, name, schools) =>
  schools.map(school => school.name === oldName ?
    ({...school, name}) : school)

The ({...school, name}) is an interesting line what it means is expand the object school and replace all name attributes with the value held by the name parameter passed in. Not the parenthesis they need to be there in order to return an object literal (I think)

Making an array with only distinct values

const colors = ['red', 'red', 'green', 'blue', 'green']

const distinctColors = colors.reduce(
  (distinct, color) =>
    (distinct.indexOf(color) !== -1) ?
       distinct :
       [... distinct, color],
  []
)

Composition

You should break the program up into small pure functions that are focused on specific tasks and eventually you will need to put these smaller functions together on example is chaining functions together.

Making an object immutable

import deepFreeze from 'deep-freeze'

deepFreeze(obj)

Source

Learning React

Serverless Architecture

Benefits

  • Reduced operational cost
    • It is outsourcing solution. You pay someone to manage servers, databases and even application logic that you might otherwise manage it yourself. Similar to benefits you get from Iaas and PaaS but we can extend this to BaaS and FaaS
  • Reduced development cost with BaaS
    • e.g. Authentication is already implemented with Auth0
  • Scaling benefits
    • Scales very well horizontally you don't have to explicitly state how scaling is handled
    • Only pay for what you use so if no one is using the app you don't pay for it unlike normal servers where you have to pay for it the entire time it is up even if no one is using it
    • Works best for inconsistent traffic
  • Reduced deployment complexity
    • Only have to upload some code

Drawbacks

  • Too much vendor control
    • Could result in system down time, cost changes, forced API upgrades
  • Vendor lock-in
    • Not always easy to switch vendors
  • Security Concerns
  • Stateless
    • You cant store anything in memory for fast retrieval across requests has to be stored in a database
  • Testing/debugging is not as simple with external/remote apps

Game Changing Tips

  1. Add -webkit-appearance: none; to forms for shit to display correctly
  2. To add padding to forms
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;         /* Opera/IE 8+ */
  1. Single quotes don't work in windows i.e. make sure your commands don't use single quotes
  2. ctrl + shift To go to a new line on windows
  3. Add a display flex in a child element for text in that child element that is already within a display: flex parent element to display text in centre
  4. windows + shift + s to get section screenshot
  5. use #! for a link that doesn't go anywhere and doesn't move the page
  6. To run node + scheduler + puppeteer use build packs for node + puppeteer (make sure node build pack comes first)
  7. alt+z to compress everything into view and alt+z again to toggle off
  8. When console.log an object the output could be misleading you may see parts of an object that are resolved afterwards. Use Object.keys(yourObject) to see the true state at runtime.
  9. Memory leaks can occur when you call setState() after a component has unmounted this can occur when you have an API call and it finishes after a component has unmounted.
  10. toFixed(NUMBER_OF_DECIMAL_PLACES) use this to round to a certain number of decimal places
  11. randomstring.lvh.me:PORT_NUMBER this will point to your local server, this is useful when you are messing around with headers
  12. Putting debugger in code and having dev tools open with stop application at that point so yo can inspect variables
  13. Use workspace settings instead of user settings. Changing workspace settings will create a .vscode folder which can be shared to keeps things consistent
  14. Follow this guide to properly setup everything https://medium.com/@gogl.alex/how-to-properly-set-up-eslint-with-prettier-for-vue-or-nuxt-in-vscode-e42532099a9c
  15. Without the <meta name="viewport" content="width=device-width, initial-scale=1.0"> when viewed on mobile it will appear zoomed out
  16. https://www.browserling.com/ Test IE using this
  17. coolors.co to create your color pallete and gradient https://uigradients.com
  18. Write/automate as much as the build and deployment process as possible because it is very easy to forget all the steps and if you just forget one it will cause issues
  19. Use this site to test slower phones https://www.webpagetest.org/
  20. To fill out pdf forms https://www.sejda.com
  21. Learn how to use typescript with react https://github.com/typescript-cheatsheets/react
  22. Fully featured data visualisation https://antv.vision/en

Vue Fundamentals

Reactivity

onStateChanged(() => {
  view = render(state)
})

How state changed function implemented

let update
const onStateChanged = _update => {
  update = _update
}

const setState = newState => {
  state = newState
  update()
}

Code formatting

Some useful scripts

"scripts": {
    "dev": "gatsby develop",
    "lint": "eslint --ext .js,.jsx --ignore-pattern public .",
    "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\"",
    "format": "prettier --trailing-comma es5 --no-semi --single-quote --write 'src/**/*.js' 'src/**/*.md'",
    "develop": "gatsby develop",
    "start": "npm run develop",
    "build": "gatsby build",
    "now-build": "npm run build",
    "fix-semi": "eslint --quiet --ignore-pattern node_modules --ignore-pattern public --parser babel-eslint --no-eslintrc --rule '{\"semi\": [2, \"never\"], \"no-extra-semi\": [2]}' --fix gatsby-node.js",
    "deploy": "now && now alias"
  }

Webpack

Replaces browserify, gulp, grunt. Leading tool to bundle CommonJS modules. At its core it is a module bundler. Takes all different files and turns them into a single file. Main benefits of bundling are modularity and network performance.

Modularity allows you to break your source code up into modules.

Network performance is gained by making only one HTTP request to get the required static files.

Additionally webpack can also handle

  • Code splitting
    • Splits code into different chunks that can be loaded when you need them.
  • Minification
    • Removes whitespace, line breaks, length variable names and unecessary code to reduce file size
  • Feature flagging
    Sends code to one or more environements when testing out features
  • Hot Module Replace (HMR)
    • Watches for changes in source code and updates modules immediately

Emerging JavaScript

Let and const

  • let allows us to scope a variable to a code block defined by {}. var only scoped a variable to a function
  • const throws an error when it is reassigned

Template strings

This allows for string interpolation when constructing a string or some HTML

Default Parameters

Similar to python when defining a parameter we can assign it a default value if it is not entered
function defaultOne(x=100) {}

Arrow functions vs Normal functions

Arrow functions do not have their own value of this they will instead use the value of the enclosing block

Destructuring Assignment

var sandwish = {
  bread: 'dutch',
  meat: 'egg',
  cheese: 'swiss'
}

var {bread, meat} = sandwich

This can also be done for arrays too

var [firstPlace] = ['firstplace', 'secondplace', 'thirdplace']

var [,,thirdPlace] = ['firstplace', 'secondplace', 'thirdplace']

Object Literal Enhancement

This is the opposite of object destrucutring. We can grab objects from the global scope and turn them into an object

var name = 'name'
var place = 'place'

var fun = {name, place}

Old vs new object syntax

var skier = { 
  name: name,
  sound: sound, powderYell: function() {
     var yell = this.sound.toUpperCase()
     console.log(`${yell} ${yell} ${yell}!!!`)
   },
   speed: function(mph) { 
     this.speed = mph
     console.log('speed:', mph)
   }
}
const skier = { name,
    sound,
    powderYell() {
        let yell = this.sound.toUpperCase()
        console.log(`${yell} ${yell} ${yell}!!!`)
    },
    speed(mph) { 
         this.speed = mph
        console.log('speed:', mph)
    }
}

Spread Operator

Expands the contents of an array

var peaks = ["Tallac", "Ralston", "Rose"]; 
var canyons = ["Ward", "Blackwood"];
var tahoe = [...peaks, ...canyons];

We can do neat things with this operator like not mutating an array to get the last element from it

var peaks = ["Tallac", "Ralston", "Rose"] 
var [last] = [...peaks].reverse()

Use spread operator to collect all items of an array

var lakes = ["Donner", "Marlette", "Fallen Leaf", "Cascade"]
var [first, ...rest] = lakes
console.log(rest.join(", ")) // "Marlette, Fallen Leaf, Cascade"

Can use spread to collect all arguments for function and place it in an array

function directions(...args) {
var [start, ...remaining] = args
var [finish, ...stops] = remaining.reverse()
      console.log(`drive through ${args.length} towns`)
      console.log(`start in ${start}`)
      console.log(`the destination is ${finish}`)
      console.log(`stopping ${stops.length} times in between`)
}
    directions(
        "Truckee",
        "Tahoe City",
        "Sunnyside",
        "Homewood",
        "Tahoma"
)

Can also use spread for objects

var morning = {
  breakfast: "oatmeal",
  lunch: "peanut butter and jelly"
}
var dinner = "mac and cheese"
var backpackingMeals = { 
  ...morning,
  dinner
}
console.log(backpackingMeals) // { breakfast: 'oatmeal', lunch: 'peanut butter and jelly', dinner: 'mac and cheese'}

The order also matters because if we placed dinner before morning then it would not replace whatever is in the morning object. e.g. this won't work

var backpackingMeals = {
  dinner,
  ...morning
}

## Promises

They make dealing with asynchronous requests easier.

``` js
const getFakeMembers = count => new Promise((resolves, rejects) => {
  const api = `https://api.randomuser.me/?nat=US&results=${count}`
  const request = new XMLHttpRequest()
  request.open('GET', api)
  request.onload = () => {
    request.status === 200 ? resolves(JSON.parse(request.response).results) : 
    rejects(Error(request.statusText))
  }
  request.onerror = (err) => rejects(err)
  request.send()
})

getFakeMembers(5).then( members => console.log(members), err => console.error( new Error("cannot load members from randomeuser.me")))

When asynchronous process fails we call rejects if it succeeds we call resolve. We can pass a callback function to the Promise object to be executed when it succeeds

Classes

class Good {
  constructor(dataInstantiatedWith) {
    this.descriptiveName = dataInstantiatedWith
  }
}

Inheritance

class Expedition extends Vacation {
  constructor(destination, length, gear) {
    super(destination, length)
    this.gear = gear
  }
  print() {
    super.print()
    console.log(`Bring your ${this.gear.join(" and your ")}`)
  } 
}

Modules

Modules represent a piece of reusable code. Previously we had to use a library that could handle importing and exporting modules.

export const print(message) => log(message, new Date())

export const log(message, timestamp) =>
  console.log(`${timestamp.toString()}: ${message}`)

///////////////////// Different file
import { print, log } from './file'
import freel from './anotherfile'

If you only want to export one variable from a module use export default

const freel = new SomeClass()

export default freel

Both export and export default can be used on any JavaScript type.

Modules in node

module.exports = is used instead of export and require is used instead of import This is called CommonJS

DOM

DOM insertions are one of the most expensive DOM API operations. In contrast updating DOM elements performs much faster.

Web Security

The number one way for attackers is through your browser extensions

Examples of XSS attacks

  • Stored XSS where your malicious code is stored and executed once retrieved
    image
  • Reflected XSS
    image

XSS Defenses: Never put unstrusted data in these places

  • Directly in a script `<script> <%- userData %> </script>
  • In a HTML comment <!-- <%- userData %>-->
  • In an attribute name <iframe <%- userData %>="myValue" />
  • In a tag name <<%- userData %> class="myElement">
  • Directly in a <style> block <style> <%- userData %> </style> older browsers allow you to load code here

Use a view library/framework with XSS protection

  • Most view libraries have XSS protection

Content Security Policy (CSP)

Define what sources you allow to download content from

  • Script tags embedded in HTML is the most common form of XSS. Banning it mitigates XSS risk considerably.
  • However sometimes we really want a little JS in our HTML. We can use cryptographic nonces that are generated per page load and the nonce must match what is in the header

Code injection into an image

We can but HTML and JS into an image and if we can rename that image then we can execute the injected code

Mitigation

  • More restrictive on file upload types and ability to access those types
  • Compress files helps drop non-visible data
  • Before allowing other attachment types, research capabilities thoroughly

Cross-Site Request Forgery

  • Takes advantage of the fact that cookies are passed along with requests
  • You can hide a form which executes your action
  • You can put a url in an image which executes you required action

Who is vulnerable to CSRF

  • Basic or cookie authentication schemes are vulnerable with the exception of client side cookie

Mitigation to CSRF

  • Use localstorage/sessionstorage
  • Pass validation in header instead
  • CSRF Token - similar to the nonce
  • Validate request origin - modern browsers send an Origin header which cannot be altered by client-side code
  • CORS where you allow only valid origins to execute on your server

Clickjacking

  • Use an iframe of website you are attacking position it in such a way that the user will click on the required place. Then hide that iframe. Make the user click on the specific place in your hidden iframe

Mitigation of clickjacking

  • X-Frame-Options HTTP response header
  • Only allow iframes from particular origins

C#/Visual Studio Quirks

  • Methods are also capitalised
  • Case sensitive variable names
  • Quickly type Console.WriteLine("hello world"); -> C.WL("helloworld");
  • String interpolation $"This is a {variable}"
  • Can format strings to display nicely for example you can display currency to the user.
String s = String.Format("The current price is {0:C2} per ounce.",
                         pricePerOunce);
Console.WriteLine(s);
  • Declaring multiple mains in your program, this can be done but you have to specify which one is the program's entry point Project > [ProjectName] Properties
  • You can use an library with the fully qualified name e.g. System.Console.WriteLIne or just type using System at the top to do things normally Console.WriteLine
  • You can do method overloading where you define the same method with different parameters in a class
  • To pass by reference use ref e.g. ref myValue
  • Extension methods add to the existing class capabilities and examples include .Any() and .First()
  • IEnumerable, List
  • The common language runtime (CLR) performs automatic memory management by using a garbage collector that reclaims the memory occupied by objects no longer in use. When there are no references to the object, then the object becomes eligible for destruction. This can be done with assigning the object to null when it is done
  • String objects are immutable, operations on strings result in a new string object being created
  • It is best to keep things private so you can easily change them without having the change other classes that depend on that class. You just have to keep the public stuff consistent
  • All classes directly or indirectly inherit from the class object an alias for System.Object
  • use using to automatically place expression in a try catch block
    using (var exampleObject = new ExampleClass()) { exampleObject.SomeMethod() }
{
  var exampleObject = new ExampleClass()
  try {
    exampleObject.SomeMethod()
  } finally {
    if (exampleObject != null) {
      exampleObject.Dispose();
  }
}
  • The null-conditional operator ?. e.g. object?.methodCall() on occurs if object is not null this can also be done on array calls array?[0]
  • Null coalescing operator ?? e.g. float someDecimal = object?.methodCall() ?? 0.0 if the left hand side is null return the right hand side
  • Add a @ in front of a string to not have to escape things with a back slash
  • If an enumerable is created after the collection has been modified then it will become invalid any calls to that enumerable will become invalid. In a foreach statement you cannot modify an enumerable

Static variables

  • Automatically initialised
  • Accessible by all instances
  • Only a reference is stored by all instances

Read only instance variables

They are like constants where you cannot modify them however they don't have to be instantly initialised

Representing floating point numbers correctly

You should not use floats or doubles when doing monetary calculations because they are just an approximation of the actual number. Use type decimal instead if you want to use one of the two use double because it can represent them more precisely

Useful data structures and associated methods

List
image

Structs and operator overloading

Use classes for most new types but use structs if

  • the type represents a single value--a complex number represents one number that happens to have a real part and an imaginary part
  • the size of an object is 16 bytes or smaller

Interfaces

They describe a set of methods and properties that can be called on an object but does not provide concrete implementations for them. You declare classes that implement them. Interfaces are useful for assigning common functionality to classes that are not related to each other. It can only contain abstract methods, abstract properties, abstract indexers, abstract events. All interface members are implicitly declared both public and abstract. In addition interfaces can extend one or more interface.

By default all interfaces being with an I e.g. IGoodInterface

Abstract classes and methods

These are classes just used for inheritance and are never instantiated

Interfaces vs Abstract classes

Use an interface when there is no default implementation to inherit

Generics

Allow us to not have to deal with type stuff so much. Generic method defined in the following way

private static void DisplayArray<T>(T[], input Array)
{
}

The issue with generics is that the compiler has to see that all types can execute the code, this is rarely possible instead we can restrict to a subset with the following:

private static T Maximum(T x, T y) where T : IComparable<T>

Investigation into the nature of JavaScript

JavaScript is single threaded programming language

A thunk is a function that has some closured state to keep track of value(s). Becomes a container around some state and you can pass it around anywhere in your program.

A synchronous thunk is a function that doesn't require any parameters except the callback so you can get the value out.

With an asynchronous Thunk we reduce the complexity of managing time in our program. The program state becomes independent of time.

function addAsync(x, y, cb) {
  setTimeout(function () {
    cb(x + y);
  }, 1000);
}

var asyncThunk = function(cb) {
 addAsync(10, 15, cb);
}

asyncThunk(function () {
  sum; // 25
});

Blocking (synchronous) vs Non-blocking (asynchronous)

  • Blocking

    • Easy to write
    • Uses multi-threading
    • Memory and context-switching overhead
  • Non-blocking/event-loop

    • Single-threaded (Which means you cannot block the thread)
    • High-concurrency with low-memory consumption
    • Great for UI and IO-bound services rather than CPU-bound (Because anything using the CPU will block everything that is happening)

All modern JavaScript engines use event driven non-blocking

  • Examples of blocking calls in JS
    • Alert, prompts
    • Synchronous file reads and friends in node

How to prevent blocking of single thread

Use callbacks. Pass a function when the task is complete

Promises

They are a thin layer of abstraction over callbacks. They help with readability because you don't have that sort of deep nesting if you need to do things in sequence when using callbacks.

sleep(1000)
  .then(() => { console.log('one'); return sleep(1000);}) 
  .then(() => { console.log('two'); return sleep(1000);})
  .then(() => { console.log('three'); })

By returning a promise we can call then on it.

Here is another example of the power of promises

fetchJSON('/user-profile')
  .then((user) => {
    return fetchJSON(`/users/${user.id}/friends`);
  })
  .then((friendIDs) => { 
    let promises = friendIDs.map((id) => {
      return fetchJSON(`/users/${id}`)
    });
    return Promise.all(promises);
  })
  .then((friends) => console.log(friends));

Here we have to do somethings sequentially and other things parallel. For example we wait until we get the user id in order to get the friends associated with it. We can then retrieve the profile of each friend in parallel by iterating over all the friends. Promise.all(iterable) returns a single promise when all the promises have inside the iterable have been resolved.

Await

We can achieve synchronous looking code with await. This has been achieved through generator functions. This idea is not related to aysnc or event loops and not about concurrency. They are just about pausing the function.

function * generatorFunc() {
  let result = fetch('/users')
  // Pause execution by yielding.
  yield result;
  // Later something caused us to resume.
  console.log('We are back');
}
async function getUsers() { 
  let result = await fetchJSON('/users') // This will pause the whole function
  console.log(result);
}

A promise always has to follow await. Can only use await inside a async function.
Async function itself returns a promise. When we await a promise the function pauses until the promise is ready (resolved)

async function getUserFriends() {
  let user = await fetchJSON('/users/user-profile')
  let friendsID = await fetchJSON(`/users/${user.id}/friends`)
  let promises = friendsID.map((id) => { return fetchJSON(`/users/${id}`) })
  let friends = await Promise.all(promises)
  console.log(friends)
}

let friends = await getUserFriends()
doSomethingCallWithFriends(friends)

No need for callbacks now with aysnc/await

Event Loop

Event loop is what allows Node.js to perform non-blocking I/O operations -- despite the fact that JavaScript is single-threaded -- by off loading operations to the system kernel whenever possible.

Since most modern kernels are multi-threaded, they can handle multiple operations in the background.

Event loop operations


   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”Œโ”€>โ”‚           timers          โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ”‚     pending callbacks     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ”‚       idle, prepare       โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚   incoming:   โ”‚
โ”‚  โ”‚           poll            โ”‚<โ”€โ”€โ”€โ”€โ”€โ”ค  connections, โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚   data, etc.  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚  โ”‚           check           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ””โ”€โ”€โ”ค      close callbacks      โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Each phase has a FIFO queue of callbacks to execute

Phases Overview

  • Times This phase executes callbacks scheduled by setTimeout() and setInterval()
  • pending callbacks executes I/O callbacks deferred to next loop iteration
  • idle, prepare only used internally
  • poll Retrieve new I/O events; execute I/O related callbacks (These are most callbacks with the exception of close callbacks and the ones scheduled by timers and setImmediate()
  • check setImmediate() callbacks invoked here
  • close callbacks some close callbacks socket.on('close')

Timers

They run after a delay specified by the user however this it is not guaranteed to execute exactly after that time because other callbacks and OS scheduling may delay it.

Closure

A way to remember and continue to access a function's scope (it's variables) even once the function has finished running.

Most common usage of closure in JavaScript is the module pattern. They let you define private implementation details (variables, functions) as well as a public API that is accessible from the outside world

this

this normally points to an object but which object it points to depends on how the function was called

How is JavaScript Asynchronous and single-threaded?

JavaScript language is single-threaded and the asynchronous behaviour is not part of the JavaScript language itself rather they are built on top of the core JavaScript language in the browser and accessed through the browser APIs.

function main(){
  console.log('A');
  setTimeout(
    function display(){ console.log('B'); }
  ,0);
  console.log('C');
}
main();

The code will be executed like this underneath the hood, that is why 'B' is actually displayed last

JavaScript is single threaded but the browser offers web apis that can execute code asynchronously for you. In node this would be C++ library calls. setTimeout is one such api call offered to us.

The event loop is very simple it just looks at the task queue and it looks at the stack if the stack is empty it pushes the first thing in the task queue onto the stack.

Weird shit

  • Return needs to have something on the same line with it otherwise nothing is returned
return (
  <div> Hello world </div>
)

Won't work

return 
(
  <div> Hello world </div>
)

IIFE (immediately invoked function expression) JS pattern

Allows us to create scope in various places and doesn't pollute the namespace

var foo = 'foo1'
(function notInGlobalNameSpace() {
  var foo = 'foo2'
  console.log('did something')
}) ()
console.log(foo)

Compiler

JavaScript compiles the code on the fly the runs them.

The general steps to compiling JS program are as follows

  1. Tokenizing/Lexing breaking up a string of characters into meaningful chunks called tokens.
    var a = 2; -> var a = 2 ;
  2. Parsing Taking a stream (array) of tkens and turning it into a tree of nested elements which collectively represent the grammatical structure of the program. This tree is called an AST (Abstract Syntax Tree)
  3. Code-Generation This is where memory allocation occurs and how your code turns into machine code to be executed example

Low-level implementation of how scoping occurs

  1. Engine: responsible for start to finish the compilation and execution of our JS program
  2. Compiler: one of Engine's friends: handles all the dirty work for parsing and code-generation
  3. Scope: another friend of Engine; collects and maintains a look-up list of all the declared identifiers (variables) and enforces rules as to how these are accessible to currently executing

Sources

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ (Event loop in node js)
https://frontendmasters.com/courses/rethinking-async-js/ (Thunks)
https://www.youtube.com/watch?v=NsQ2QIrQShU (Callbacks, async/await, promises)
https://www.youtube.com/watch?v=8aGhZQkoFbQ (Event loops explained)

My VSCode shortcuts

Some of these shortcuts are not set by default in that case you need to set it yourself cmd + shift + p and choose open keyboard shortcuts. Also these are only for Mac

  • New file ctrl + shift + n
  • New folder ctrl + shift f
  • Collapse all folders ctrl + shift c
  • Switch panes cmd + option + arrow key
  • Split pane ctrl + \
  • Toggle left menu cmd + b
  • option + shift + o remove unsed variables
  • option + cmd + t delete all panes to the right
  • F12 to rename a variable and all its instances
  • cmd + . for quick fix suggestions
  • cmd + ctrl + shift + d skip selection

Typescript

Does not exist at runtime you can think of it as a static analysis tool. Therefore if you make a network request or user enters some data typescript will not be able to type check for you since they occur at run time.

Functional vs Class React components

  1. Functional components are easier to read and test
  2. Less code
  3. Easier to separate container and presentational components and not so confusing because you don't need to reason with your component's state
  4. Performance boost

UI Inspiration

Using motion

Interacting with a website should feel natural using animations/springs help with that.
https://github.com/chenglou/react-motion
https://github.com/pmndrs/react-spring

Nice websites

Dude with crazy designs

http://lorenzocadamuro.com/

Interesting websites

https://the-guild.dev/connected-build

Get good quality svg images

https://undraw.co/

Nice designs

https://codepen.io
https://give-n-go.co

Great animations

https://tobiasahlin.com/moving-letters/



image
image

Beautiful font

image

Cool Teaser

image

Production Checklist

Here is a list of essential high level things to help with building high quality apps. They have been created during my time in the trenches...

  • Implemented appropriate Security Headers https://securityheaders.com/ there should be libraries to help e.g. https://helmetjs.github.io/
  • Loads okay on a slow connection and slow hardware, can simulate this in dev tools
  • Lighthouse audit
  • Continual monitoring of vulnerabilities https://snyk.io/ https://github.com/renovatebot/renovate
  • Catching errors https://sentry.io/welcome/ https://logrocket.com/
  • App handles a token expiry gracefully
  • App works nicely in mobile view
  • Deployments are automated where it makes sense (It's so easy to forget a step in the deployment process e.g. building the assets or bumping up the version)
  • Both www. or non www. domains work and should redirect to one for SEO purposes
  • An automated package updater e.g. renovate bot
  • A health check tool like https://www.pingdom.com/ or https://uptimerobot.com/
  • App handles network errors gracefully
  • App always disables appropriate inputs to prevent a user from doing dumb things e.g. if a login button should be disabled while submitting data to server
  • Check your emails are not reported as spam https://www.mail-tester.com/ this will need to be continuously monitored
  • Appropriate documentation supplied
    • Description of data models e.g. Database schema
    • File structure
    • Technical decision records (contentious / difficult decisions)
    • Routes with example payloads this can be covered with swagger
    • Purpose of the project and general description.
    • Todo list.
    • License

Following checks should run on PR

  • Automated deploy on PR e.g. now
  • Automated testing on PR e.g. Travis
  • Automated security testing on PR e.g. Synk
  • Automated lighthouse score (you could go next level and configure to test on different platforms with webpagetest
  • Automated code reviews with LGTM

Example functional vs normal approach

 //////////////// Basic implementations
 // Log Clock Time every Second
setInterval(logClockTime, 1000); 

function logClockTime() {
      // Get Time string as civilian time
      var time = getClockTime();
      // Clear the Console and log the time
      console.clear();
      console.log(time);
}

function getClockTime() {
      // Get the Current Time
      var date = new Date(); var time = "";
      // Serialize clock time
      var time={
            hours: date.getHours(), minutes: date.getMinutes(), seconds: date.getSeconds(), ampm: "AM"
      }
      // Convert to civilian time
      if (time.hours == 12) { time.ampm = "PM";
      } else if (time.hours > 12) { time.ampm = "PM"; time.hours -= 12; }

      // Prepend a 0 on the hours to make double digits
      if (time.hours < 10) { time.hours = "0" + time.hours;
      }
      // prepend a 0 on the minutes to make double digits
      if (time.minutes < 10) { time.minutes = "0" + time.minutes;
      }
      // prepend a 0 on the seconds to make double digits
      if (time.seconds < 10) { time.seconds = "0" + time.seconds;
      }
      // Format the clock time as a string "hh:mm:ss tt"
      return time.hours + ":" + time.minutes + ":" + time.seconds + " "
      + time.ampm;
}

//////////////// Functional version
const oneSecond = () => 1000
const getCurrentTime = () => new Date()
const clear = () => console.clear()
const log = message => console.log(message)

const compose = (...fns) =>
    (arg) =>
        fns.reduce( (composed, f) => f(composed), arg )

const serializeClockTime = date => 
    ({
        hours: date.getHours(),
        minutes: date.getMinutes(),
        seconds: date.getSeconds()
    })

const civilianHours = clockTime => 
    ({
        ...clockTime,
        hours: (clockTime['hours'] > 12) ?
            clockTime['hours'] - 12 :
            clockTime['hours']

    })

const appendAMPM = clockTime =>
    ({
        ...clockTime,
        ampm: (clockTime.hours > 12) ? 'PM' : 'AM'
    })

const display = target => time => target(time)

const formatClock = format => 
    time => 
        format.replace("hh", time.hours)
              .replace('mm', time.minutes)
              .replace('ss', time.seconds)
              .replace('tt', time.ampm)

const prependZero = key =>
    clockTime =>
        ({
            ...clockTime,
            [key]: (clockTime[key] < 10) ?
                '0' + clockTime[key] :
                clockTime[key]
        })

const convertToCivilianTime = clockTime =>
    compose(
        appendAMPM,
        civilianHours
    )(clockTime)

const doubleDigits = civilianTime =>
    compose(
        prependZero('hours'),
        prependZero('minutes'),
        prependZero('seconds')
    )(civilianTime)

const startTicking = () =>
    setInterval(
        compose(
            clear,
            getCurrentTime,
            serializeClockTime,
            convertToCivilianTime,
            doubleDigits,
            formatClock('hh:mm:ss tt'),
            display(log)
        ),
        oneSecond()
    )

startTicking()

Not sure what to call this, this hurts my brain because I don't understand prototypes much

What occurs when you call new on a function

Before JS had classes new when called on a constructor function would create an object {} and point this inside the constructor function to that object so we can assign stuff like this.name. Also anything place in ConstuctorFuncName.prototype would be available to all objects created with this constructor function.

prototype of a class or function does not point to the prototype of that value

The prototype chain is more like proto.proto.proto rather than prototype.prototype.prototype. For example the prototype of a function or class is the __proto given to all objects newed with that class or function. So to look up properties JavaScript does this instance.__proto__.__proto__ chain continues until it finishes or finds value/function

class Greeting extends React.Component {
  render () {
     return <p>Hello</p>
   }
}

let c = new Greeting()
console.log(c.__proto__) // Greeting.prototype
console.log(c.__proto__.__proto__) // React.Component.prototype
console.log(c.__proto__.__proto__.__proto__) // Object.prototype

c.render() // Found on c.__proto__ (Greeting.prototype)
c.setState() // Found on c.__proto__.__proto__ (React.Component.prototype)
c.toString() // Found on c.__proto__.__proto__.__proto__ (Object.prototype)

In React to check if a class extends React component follow is implemented

class Component {}
Component.prototype.isReactClass = {}

// Then to check own component
OwnComponent extends React.Component {}
console.log(OwnComponent.prototype.isReactClass) // Yes

Could have used a boolean value but Jest didn't handle this well in the early days

The point of this code in React is to determine whether we can call new or not on user function or class if isReactClass returns true then it must be a React class hence it must be a class and not a function so we can call new on it.

Reading PWA web architectures by Google

https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures

Surprisingly useful

App Shell: The minimal HTML, CSS and JavaScript and any other static resources that provide structure for your page minus the actual content specific to a page. In other words it is the minimal resources required to get your app off the ground. Sites that are all static content are said to be 100% app shell.

Sites rendering the same code on the server and client sides use a approach know as universal (or Isomorphic) JavaScript. Here is the origins of the phrase "Universal JavaScript"

Ryan Dahl has the crazy idea to pair Google's V8 JavaScript runtime with libev so developers would have a way to run their JavaScript outside the browser.

Whenever possible it is best practice to combine SSR and CSR so that your first render of the page is on the server side. Traditionally it has been difficult to do this because the client and server side have been done in different environments and languages.

PWA Architectural Patterns

PWAs can be built with any architectural style (SSR, CSR, both) but service workers imply some subtle changes in how you build your application architecture.

JavaScript Quirks

  • Everything equals itself except for NaN == NaN
  • undefined and null and very similar in fact undefined == null
  • Infinity - Infinity gives us NaN
  • 0 NaN and empty strings "" count as false
  • typeof null returns an object this is a bug in JS that will likely never be fixed because too much code relies on this to work
  • functions are a subtype of objects
  • When to use === vs ==
    • == checks for equality with coercion and === checks for equality without coercion
    • if either value could be true or false use ===
    • if either value oculd be 0 "" [] use ===
    • In all other cases it is safe to use ==
  • If comparing two non-primitive values like objects including function and array both == === just check they refer to the same thing and not match the underlying values
  • False becauese the string gets converted to a NaN which is neither greater than or equal to anything
var a = 42
var b = "foo"

a < b // false
b > a // false
a == b // false
  • var x = function bar() {alert('helo')} even though the function is bar you can only invoke it with x()
  • Falsy values
    • ""
    • 0, -0, NaN
    • null, undefined
    • false
  • Arrays are coerced into strings
var a = [1,2,3]
var b = [1,2,3]
var c = '1,2,3'
a == c //true
b == c // true
a == b // false

Next tips and tricks

Masking url

<Link as="url mask" href="/actualurl"></Link>

Lazy loading

There is automatic code splitting but sometimes we want to lazy load things for fast initial load of a pwa

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.