Skip to content

Instantly share code, notes, and snippets.


Donald Pipowitch donaldpipowitch

View GitHub Profile
donaldpipowitch / get-nice-upper-bound.ts
Created Nov 13, 2020
Nice upper bound (e.g. for charts, ticks, scales)
View get-nice-upper-bound.ts
function getNiceUpperBound(value: number) {
const zeroCount = String(Math.round(value)).length - 1;
const factor = Math.pow(10, zeroCount);
return Math.ceil(value / factor) * factor;
const upperBound = getNiceUpperBound(3464634); // 4000000
View use-stable-memo.ts
import { DependencyList, useState, useEffect, useRef } from 'react';
// use this instead of useMemo of you need a stable value
// see
export function useStableMemo<T>(factory: () => T, deps: DependencyList): T {
const [value, setValue] = useState<T>(factory);
const firstRun = useRef(true);
() => {
donaldpipowitch / use-location-state.ts
Created Jul 22, 2020
useLocationState: a glorified location.state for React Router as a hook
View use-location-state.ts
import { useState, useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { useSessionStorage } from './use-storage'; // see
type UseLocationStateOptions<T> = {
defaultValue?: T;
scope?: string;
filter?: (value: T) => boolean;
donaldpipowitch / mocked-storage.tsx
Last active Jul 22, 2020
useSessionStorage and useLocalStorage for easy mocking - similar to MemoryRouter in react-router, but for storage
View mocked-storage.tsx
import React, { FC, useMemo } from 'react';
import {
} from './use-storage';
// this is just a dumb mock of the storage interface
class MemoryStorage implements Storage {
private data: Record<string, string> = {};
donaldpipowitch / index.js
Created Jul 7, 2020
ESLint rule to check for round brackets in Jest `test` names. (Doesn't play nicely with --testNamePattern without escaping.)
View index.js
// @ts-check
/** @type {import("eslint").Rule.RuleModule} */
const rule = {
meta: {
docs: {
description: `If you use a Jest test name like "hello (world)" you can't run \`$ jest -t "hello (world)"\` to select this test.`,
fixable: 'code',
donaldpipowitch / index.js
Last active Jul 7, 2020
ESLint rule to check for duplicated exported names.
View index.js
// @ts-check
/** @type {import("eslint").Rule.RuleModule} */
const rule = {
meta: {
docs: {
description: `You can export a type and a value with the same name in the same file, but that confuses refactoring tools.`,
create(context) {
donaldpipowitch /
Created Jul 1, 2020
Cheat Sheet for various Brackets

Know your brackets!

  ( ) – parentheses, round brackets, first brackets
  { } – braces, curly brackets, second brackets, moustache brackets 👨🏻
  [ ] – square brackets, third brackets
  ⟨ ⟩ - angle brackets (aka. _not_ less-than/greater-than signs 👀)
  ‹ › - angle quotes (aka. _not_ less-than/greater-than signs 👀)
  < > - less-than/greater-than signs
donaldpipowitch / index.tsx
Created Jun 27, 2020
Example how to use 'amazon-cognito-identity-js'
View index.tsx
import {
} from 'amazon-cognito-identity-js';
import React, { FC, useState } from 'react';
donaldpipowitch /
Last active Nov 18, 2019
React - Error Boundary strategy

One cool feature of React which isn't highlighted that often are "error boundaries".

Error boundaries can catch errors which are thrown inside your component during a lifecycle. You can use them in very fine-granular levels wrapping very small components (but I rarely see this) or you can wrap your whole app and show some fallback content, if an error happens. But you can also wrap something in between those extrem ranges and add a proper reset. Also it's not a hidden secret how to do that I haven't see a lot of people talking about that. So here is a small example which use react-router-dom to do that. You can see the complete example here.

Let's imagine you have the following app:

import * as React from 'react';
import { render } from 'react-dom';
import { Link, BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
donaldpipowitch / example.tsx
Created Nov 6, 2019
Mock Upload Progress with axios-mock-adapter
View example.tsx
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
const mock = new MockAdapter(axios);
// this mocks a request which is always at 40% progress
mock.onPost('/upload-1').reply((config) => {
const total = 1024; // mocked file size
const progress = 0.4;
if (config.onUploadProgress) {