The Elevator Pitch from a Data Strategist

When people asked what I do for a living at conferences or parties, I told them I run data strategy. Their first response was “oh, that’s cool”. Then they paused for a moment and asked “what do you do exactly?”

After spending fifteen minutes explaining all the aspects of my job, I either totally confused my audience or bored them to death.

So I set out to develop an elevator pitch, something as punchy as “I am a photographer who specializes in marine life”. I thought I could get some help from online job postings. Searching “data strategy” on LinkedIn returned 84 listings. Few of them described what I do. By contrast, the search on “data scientist” returned 40 times more results.

I was not hired per a job description. I was lucky to convince Eventbrite to create the role for me.

My argument was pretty simple: think of all the data-related challenges the company faces, how many of them are technical, how many are organizational?

Most data-driven organizations have the following data pipeline.
Data Pipeline

Continue reading

Engineering + Accounting for Marketplace Businesses

Eventbrite Principal Product Manager Ryan D’Silva and Chief Architect Adam Sussman cover how there’s a deep product need where engineering and finance meet, particularly if you’re a marketplace. While there are solutions available, none do the job particularly well and most marketplaces have built their own solutions at great cost. We’d like to shed some light on the problem and share what we’ve learned so far.

Learning ES6: Generators as Iterators

electric-generator

I feel like all the articles in the Learning ES6 series have been leading up to generators. They really are the feature most JavaScript developers are excited about in ECMAScript 6. They very well may be the future of asynchronous programming in JavaScript. That’s definitely something to get excited about!

Generators can be used both as data producers and data consumers. In this post, we’re going to look at how generator functions are a much more convenient way to produce data and and create iterators. It’s the simpler way to use generators. In the last article we covered iterators & iterables, so you may need to familiarize yourself with that before looking at generators as iterators.

TL;DR

A generator function is a special type of function that when invoked automatically generates a special iterator, called a generator object. Generator functions are indicated by function* and make use of the yield operator to indicate the value to return for each successive call to .next() on the generator.

function* range(start, count) {
    for (let delta = 0; delta < count; delta++) {
        yield start + delta;
    }
}

for (let teenageYear of range(13, 7)) {
    console.log(`Teenage angst @ ${teenageYear}!`);
}

Feel free to clone the Learning ES6 Github repo and take a look at the generators code examples page showing them off in greater detail.

With out further ado, let’s keep reading.

Continue reading

Learning ES6: Iterators & iterables

iterators-gonna-iterate

We’ve talked about promises and new collection APIs, so now we’re finally going to talk about iterators & iterables. They’ve come up in passing in the last couple of posts, so it’s about time we talk about them deeply.

TL;DR

Iterators provide a simple way to return a (potentially unbounded) sequence of values. The @@iterator symbol is used to define default iterators for objects, making them an iterable.

Continue reading

Learning ES6: New Collections

collections

Let’s continue focusing on the new functionality introduced with ES6 in the Learning ES6 series. The main focus in the next few articles will be all about asynchronous programming. We’ll ultimately talk about generators, but there are a few building blocks we need to get through first. The new collections we’ll talk about now aren’t really building blocks for generators, but I feel that they are important to learn. In addition, they are types of iterables which we’ll deep dive into in the next article.

TL;DR

ES6 introduces four new efficient collection data structures to mitigate our ab-use of object and array literals.

Continue reading

The Lifecycle of an Eventbrite Webhook

At Eventbrite, we have a feature called webhooks.  Webhooks can be thought of as the opposite of an API call.  When using our API, developers either ask us for information, or hand us information.  Both of these are initiated by you.  In a webhook, we proactively notify developers (via an HTTP POST with JSON content) when actions happen on our site.  The actions we currently support are as follows:

  • Attendee data is updated
  • An attendee is checked in via barcode scan
  • And attendee is checked out via barcode scan
  • An event is created
  • And event is published
  • An event is unpublished
  • Event data is updated
  • Venue data is updated
  • Organizer data is updated
  • An order is placed
  • An order is refunded
  • Order data is updated

Webhooks are relatively simple to create.  You can create/delete them in our admin web interface.

Screenshot 2016-07-28 10.22.49

Screenshot 2016-07-28 10.25.46

Continue reading

Eventbrite and SEO: How does Google find our pages?

One thing that took me by surprise when I started researching SEO was that when a user enters a search term, the results are gathered from Google’s representation of the web not the entire web. For a page to be included in its index, Google must have already parsed, and stored the page’s contents in its databases.

To do this, automated robots known as spiders or crawlers scan the internet for links leading to pages they can index. These crawlers will begin scanning one page, then follow the links they find to then scan and index those pages.

webCrawlers

Continue reading

Learning ES6: Promises

Pinky Swear

Like clockwork the Learning ES6 series continues on, looking at promises. It will be the first feature we’ve looked at in this series that really is more than syntactic sugar. But promises aren’t entirely new to JavaScript. They’ve existed for quite some time in helper libraries. ECMAScript 6 now brings native promise support to JavaScript via the Promise API. Let’s jump right in!

TL;DR

A promise represents the eventual result of an asynchronous operation. Instead of registering a callback in the call to an async function, the function returns a promise. The caller registers callbacks with the promise to receive either a promise’s eventual value from the async operation or the reason why the promise cannot be fulfilled.

// Creating a promise wrapper for setTimeout
function wait(delay = 0) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, delay);
    });
}

// Using a promise
wait(3000)
    .then(() => {
        console.log('3 seconds have passed!');
        return wait(2000);
    })
    .then(() => {
    	console.log('5 seconds have passed!');
    	x++; // ReferenceError triggers `catch`
    })
    .catch(error => {
    	// output: ReferenceError
    	console.log(error);
    })
    .then(() => {
    	// simulate `finally` clause
    	console.log('clean up');
    });

Did you notice the use of default parameters and arrow functions too? If you’re unfamiliar with those ES6 features, you should check out the articles detailing how they work. Interested in learning more about ES6 promises? Clone the Learning ES6 Github repo and take a look at the promises code examples page showing off the features in greater detail.

Well you’ve come this far. You might as well keep going!

Continue reading

The Realistic Code Reviewer, Part II

Once you have a strong foundation for being a realistic code reviewer, you’re finally ready to move into the actual code itself.

Rely on established patterns more than personal style.

A common mistake in a code review is recommending things you’re used to seeing rather than well-documented patterns. The problem with this approach—besides reflecting a lack of thoughtfulness or desire find the best solutions—is it can create a lack of trust. If your ego and personal preferences get in the way, you’ll lose the trust and confidence of the author—and the code suffers as a result.

Never forget: the perspective we offer should be a helpful flag for the author, not simply an opinionated comment from someone who isn’t the one actually writing the code.

Continue reading

Learning ES6: Classes

classes

We’re going from enhanced object literals that look a lot like classes to actual classes in ES6. We’ll learn, however, that these aren’t really classes, but syntactic sugar over the existing prototype functions in JavaScript. Let’s continue on with the Learning ES6 series series!

TL;DR

ECMAScript 6 provides syntactic sugar over the prototype-based, object-oriented pattern in JavaScript. ES6 classes provide support for constructors, instance and static methods, (prototype-based) inheritance, and super calls. Instance and static properties are not (yet) supported.

// Define base Note class
class Note {
	constructor(id, content, owner) {
		this._id = id;
		this._content = content;
		this._owner = owner;
	}

	static add(...properties) {
		// `this` will be the class on which
		// `add()` was called increment counter
		++this._idCounter;

		let id = `note${this._idCounter}`;

		// construct a new instance of the note passing in the
		// arguments after the ID. This is so subclasses can
		// get all of the arguments needed
		let note = new this(id, ...properties);

		// add note to the lookup by ID
		this._noteLookup[id] = note;

		return note;
	}

	static get(id) {
		return this._noteLookup[id];
	}

	// read-only
	get id() { return this._id; }

	get content() { return this._content; }
	set content(value) { this._content = value; }

	get owner() { return this._owner; }
	set owner(value) { this._owner = value; }

	toString() {
		return `ID: ${this._id}
			Content: ${this._content}
			Owner: ${this._owner}`;
	}
}

// Static "private" properties (not yet supported in class syntax)
Note._idCounter = -1;
Note._noteLookup = {};

class ColorNote extends Note {
	constructor(id, content, owner, color='#ff0000') {
		// super constructor must be called first!
		super(id, content, owner);
		this._color = color;
	}

	get color() { return this._color; }
	set color(value) { this._color = value; }

	toString() {  // computed method names are supported
		// Override `toString()`, but call parent/super version
		// first
		return `${super.toString()}
			Color: ${this._color}`;
	}
}

// `add` factory method is defined on `Note`, but accessible
// on ColorNote subclass
let colorNote = ColorNote.add('My note', 'benmvp', '#0000ff');

// output: ID: note0
// Content: My Note
// Owner: benmvp
// Color: #0000ff
console.log(`${colorNote}`);

// output: true
console.log(Note.get('note0') === colorNote);

This is just a quick example of how ES6 classes work. Be sure to clone the Learning ES6 Github repo and take a look at the classes code examples page showing off the features in greater detail.

The example also uses default parameters, rest parameters, and the spread operator so you may want to revisit the relevant articles if you’re not familiar. It also makes use of template strings for string interpolation, so you should read up on that as well.

Continue reading