Skip to content

Instantly share code, notes, and snippets.

@joeytwiddle
joeytwiddle / optional.js
Last active November 12, 2019 08:14
Getting properties from an object which might be null
// A common situation in Javascript:
//
// We have a variable `obj`, and we want to get `obj.foo.bar`
//
// But `obj` might be null or undefined, or `obj.foo` might be null or undefined
//
// So how can we try to get `obj.foo.bar` without risking an error?
// Here are a few different ways to do that. Which one is clearest?
@joeytwiddle
joeytwiddle / Basic_React_Gotchas.md
Last active May 20, 2020 05:40
Some things we learned in the first few months of using React

Basic React Gotchas

Some things we learned in the first few months of using React (2017).

Note: This document might not be easy for complete beginners. It was originally written for someone who already knew React fairly well, and wanted some suggested talking points for a presentation they were planning to give to beginners. I have added some examples over time, but there may be room for more.

Also note: This document was written before React hooks, when we were using ES6 classes for components. Some of the advice (especially the earlier sections, and some of the error messages) does not really apply when using hooks.

Hooks have a number of new and different gotchas, deserving of their own document!

Be Overly Liberal with Thresholds, not Slightly Conservative

A mistake I often see in software development is the way people choose thresholds. The developer is told they need to limit certain types of activity, for logical reasons, but they set the limits too strictly.

I recommend:

When setting a threshold, be generous to the user, and then double that. If a high threshold will still satisfy your requirements, then choose

@joeytwiddle
joeytwiddle / objUtils.js
Created June 21, 2018 09:57
Some Array functions for Objects
// The functional way
const objUtils = {
mapProps(obj, mapFn) {
return Object.entries(obj).reduce((a, [key, value]) => (
{ ...a, [key]: mapFn(value) }
), {});
},
filterProps(obj, filterFn) {
return Object.entries(obj).reduce((a, [key, value]) => (
@joeytwiddle
joeytwiddle / async-await-forEach-alternatives.md
Last active March 26, 2024 16:12
Do not use forEach with async-await

Do not use forEach with async-await

TLDR: Use for...of instead of forEach() in asynchronous code.

For legacy browsers, use for...i or [].reduce()

To execute the promises in parallel, use Promise.all([].map(...))

The problem

@joeytwiddle
joeytwiddle / converting_js_types.md
Last active June 23, 2018 16:04
Converting between types in Javascript

When you have a variable of one type but you want to convert it to another type, there are a few options available to you.

Here are some of the most popular methods:

+=================+===================+=========================+
|                 |                   |                         |
|    Goal         |    Short form *   |    Long form            |
|                 |                   |                         |
@joeytwiddle
joeytwiddle / Use_throw_instead_of_reject.md
Last active February 17, 2023 05:57
Using throw instead of Promise.reject()

I recommend using throw over return Promise.reject() when possible, because:

  1. If you are inside "promise-land" then your throw will be automatically converted into a rejected promise.
  2. But it is shorter, which makes it easier to read.
  3. And it retains some parity between synchronous and asynchronous code. (It will continue to work as expected if those lines were extracted into a synchronous function.)
  4. Also, throw can be used to break out of a stack of deeply nested synchronous function calls. (Returning a rejection will only pass it up one level. Of course, we shouldn't be returning rejections from sycnhronous functions anyway.)

Although throwing an error is not safe inside callback functions (which are often called from the engine, without a surrounding try-catch wrapper), it is entirely safe to throw from inside an async function (or from within a .then() handler function), because in those cases the throw will be automatically converted into a rejected promise.

Situations where

async function getFoo (bar) {
const baz = 2 * bar;
const root = await asyncSqrt(baz);
return 2 * root;
}
// Is the same as
@joeytwiddle
joeytwiddle / tagged_templates_es6_es5.js
Last active March 21, 2018 15:16
What do ES6 tagged templates do?
/*
* A tagged template happens when we call a function with a template string, but without parentheses.
*
* exampleFunc`template ${foo} string`
*
* What this does is to break the template down into the pure string parts, and the expressions.
*
* The function will be given an array as its first argument, containing all the strings.
* And the remaining arguments will be the evaluated expressions.
*
@joeytwiddle
joeytwiddle / start-mongo-replset.sh
Last active August 31, 2023 16:51
Script to start a mongodb cluster with three shards, for MongoDB 3.4
#!/usr/bin/env bash
set -e
# This script will start three shards, a config server and a mongos, all on the current machine.
#
# It was written for Mongo 3.4, based on https://docs.mongodb.com/manual/tutorial/deploy-shard-cluster/
#
# This script is only for testing purposes. In production, you would run each of these servers on a different machine.
#
# If you do run this, please ensure that your machine has a few gigs of swap space. mongod indexes will happily