Skip to content

Instantly share code, notes, and snippets.

View tomprogers's full-sized avatar

Tom Rogers tomprogers

  • Minneapolis, MN
View GitHub Profile
@tomprogers
tomprogers / react-native-list-view-eg.js
Last active May 20, 2016 19:30
Example code showing how to work with react-native's ListView, with sticky headers and lots of explanatory comments
// NOTE: I'm using a few ES6 features, like Arrow Functions and default argument values
// Hopefully they don't trip you up while reading this.
import React, { Component, ListView } from 'react-native';
import Moment from 'moment'; // only needed for my example
// I reuse this configuration everywhere. As a rule, each component creates just one of them,
// and since changing the dataset doesn't require mutating this object, I define it as a const.
//
@tomprogers
tomprogers / item-property-tallies.js
Created August 24, 2016 18:00
algorithm for counting the names and datatypes of properties of a set of (hopefully) similarly-shaped object
// before running this, define ITEMS as an array of objects whose props you wish to examine
items.reduce((tallies, asset) => {
Object
.keys(asset)
.forEach((prop) => {
if(tallies.hasOwnProperty(`${prop} (${typeof asset[prop]})`)) {
console.log(`has ${prop} (${typeof asset[prop]})`);
tallies[`${prop} (${typeof asset[prop]})`] += 1;
@tomprogers
tomprogers / browser.js
Last active January 19, 2017 22:23
I wanted to find out which HTTP status codes cause fetch to resolve, and which to reject
/**
* Map HTTP error codes to fetch's .then/.catch behavior
* List based on https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
*/
let codes = [
{"code": "100", "text": "Continue"},
{"code": "101", "text": "Switching Protocol"},
{"code": "200", "text": "OK"},
{"code": "201", "text": "Created"},
@tomprogers
tomprogers / auto-persister.js
Last active April 30, 2017 20:45
I wish this existed so I could use it in my Electron app
import Path from 'path';
import AppPaths from 'app-paths';
import Persist from 'auto-persister';
let settings = Persist.manageFile({
path: Path.join(ApPaths.ConfigFile, 'default.myapp-settings'),
json: true, // read & write will marshall JSON automatically
autocreate: true, // file (and parent dirs) will be immediately created if they don't already exist
initialData: DefaultSettings, // value that will be returned if file doesn't exist, and that will be written if autocreate true
@tomprogers
tomprogers / playground.md
Created May 15, 2017 21:20
needless eloquence

one of those moments of programming eloquence you hope for, discovered to be unneeded immediately upon finishing it

the final code:

handleWordClick = (word, event) => {
	let isShiftClick = (this.state.shiftActive);
	let [ hasClickFn , hasShiftClickFn ] = [ 'onClick', 'onShiftClick' ].map((p) => (typeof this.props[p] === 'function'));
	
@tomprogers
tomprogers / css-transform-rotate3d.css
Created January 14, 2018 16:53
micro explainer of CSS 3D transform
// x : lean back
// y : revolving door from front
// z : twist clockwise
// transform: rotate3d(0,1,1,45deg);
@tomprogers
tomprogers / song-parser.js
Last active July 27, 2018 00:32
Script for parsing the list of favorite songs on soma.fm into TSV format
// Step 1: open somafm player
// Step 2: click "Favorite Songs"
// Step 3: drag-select all the text from the first song title to shopping cart on last row
// Step 4: copy & paste that text into text2tsv in JS console
// Step 5: paste result into Google Docs and you have a spreadsheet
const text2tsv = (text) => text.split('\n\n \n')
.map( r => r.trim().split('\n\n') )
.map( t => ({ artist: String(t[0]).trim(), title: String(t[1]).trim() }) )
.map( t => `${t.artist}\t${t.title}` )
@tomprogers
tomprogers / sublime-project-study.js
Created October 16, 2018 01:45
Script that reads all *.sublime-project files in a directory and aggregates their values
console.clear()
const FS = require('fs')
async function readdir(path) {
return new Promise((resolve, reject) => {
FS.readdir(path, (err, data) => {
if(err) reject(err)
else resolve(data)
})
@tomprogers
tomprogers / guidelines.md
Last active June 1, 2021 04:55
javascript coding guidelines

Javascript coding guidelines

These are listed in no particular order, but are numbered so they can referenced more easily.

  1. No interface should accept data that is not necessary for it to do its job. "Interface" includes: HTTP APIs (e.g. REST), function & method signatures, and React Component props, among others.
  2. Functions and methods should never mutate their arguments. Avoid patterns that rely on mutation of arguments.
  3. Prefer "flatter" codepaths. Nesting lots of if / else statements is hard to follow and re-organize. Bail early using return instead of nesting subsequent code.
  4. Prefer flat data structures instead of deeply nested objects.
  5. If the majority of a routine is inside a loop, extract the core of the loop into a separate routine that operates on a single item.
  6. Extract magic strings and numbers from logic. At minimum, they should be declared as constants at the top of the file that uses them. Ideally, constants that influence observable behavior should be provided by a const
@tomprogers
tomprogers / react-native-list-view-clone-args.js
Created May 20, 2016 20:10
An explanation of the structures and interpretations of the arguments to cloneWithRowsAndSections
// somewhere, you had to set this up
const LVDS = new ListView.DataSource({
getSectionHeaderData: (blob, sectionId) => blob.sectionData[sectionId],
getRowData: (blob, sectionId, rowId) => blob.rowData[rowId]
});
// ... and then you had to feed data into it with this:
let newListData = LVDS.cloneWithRowsAndSections(blob, sectionIds, rowIdsBySection)
// but what do blob, sectionIds, and rowIdsBySection look like, and how are they used internally by ListView?