Josh Pitzalis

Learning about conversion and retention.

Page 2


Why in the world would anyone want to freelance?

This is a caption

Being an independent contractor is a shit ton of work. You have to do what you do, and then run a business at the same time.

If you thought freelancing was an easy way to start making some money on the side, you are wrong.

If all you want to do is be paid to do something you love, you are better off finding a job. You’ll get a nice, steady pay-check at the end of every month, and plenty of time to practice the skill of your craft.

Freelancing only makes sense if there is a change you want to make. As an independent contractor, you get to make a living making the difference you want to make in the world. Nobody gets to tell you otherwise. You get to decide who you work for, what you do, and how you do it. Freelancing means being free to make your own choices, choices that you are ultimately responsible for.

I’m putting together a free online course that helps you avoid a lot of...

Continue reading →


React Testing Library and Redux Observable

You can use the test scheduler to test sequences in epics but integration testing breakdown if you don’t include redux observable in your test redux wrapper.

Here is how I successfully managed to integrate redux observable with react testing library by mocking out the store. This wrapper replaces the default react-testing-library render method with a render method that gives components access to redux, react-router and redux observable in a test environment.

import React from 'react';
import { render as rtlRender } from '@testing-library/react';
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import { createEpicMiddleware } from 'redux-observable';
import { rootReducer, rootEpic, dependencies } from './store';

function configureStore(initialState) {
...

Continue reading →


Redux Observable Loops

You can make redux complicated but at the most fundamental level, you have a view layer that lets you fire actions that can update the state. There is middleware and actions hit reducers which update the store, but let’s consider those implementation details. Practically speaking, it’s a tiny action loop where View > Action > State.

Redux observable introduces a separate action loop that runs alongside the tiny loop. The view layer lets you fire actions that trigger epics, which can fire off more actions, that can update the state. So it’s View > Action > Epic > Action > State.

This diagram helped me put all this all together.

PNG image-0FBFB8DA8517-1.png

A few important details:

  1. All actions will run through the tiny loop before they run through the epic loop.
  2. All Epics must return an action or it’s doom.
  3. If your epic returns the same action it received, you will create an infinite loop of doom.
  4. If your...

Continue reading →


Using Redux Observable For Async Stuff

Redux doesn’t handle async work too well. Thunk is the go-to solution, but it’s not always great for testing.

Here is how to do a basic async data fetch with redux observable;

export const exampleEpic = (action$, state$, { later }) =>
  action$.pipe(
    ofType('projects/updateTitle'),
    debounceTime(1000),
    switchMap(({ payload }) =>
      from(later(2000, payload)).pipe(
        map(res => ({
          type: 'projects/fetchFulfilled',
          payload: res,
        }))
      )
    )
  );

Thunks are called epics in redux observable. All epics take three parameters (action$, state$, { dependancies }). The last two are optional.

The action$ parameter is a stream of all redux actions emitted over time. state$ is the state of your redux store. dependencies can contain any side effects that you want to use in your epic. Passing in side effects as dependencies is super handy...

Continue reading →


Week Six

It’s been six weeks since we launched Client Tree.

Client Tree is an app that helps freelancers find clients by word of mouth. It reminds you to stay in touch with people and help them in meaningful ways.

Like any business, getting an app off the ground means keeping at least three balls in the air. You have to build the product, promote it and get feedback from the people who are using it, all at the same time. There are always too many most-important things to do.

To keep it simple, at least on the product side of things, we only track one metric.

retention8dec.png

This chart shows you the number of people who have continued to use the app after they first signed up. So 100% of the people used the app in the week they signed up. Only 25% came back to use it again after the first week.

That number has been steady for the last 5 weeks. This is a good sign. This means that a quarter of the people...

Continue reading →


Setting Up Redux Observable

If you are adding redux observable to a new redux project, the first step is to install it along with RXJS

npm i redux-observable rxjs

The next step is to set up the middleware.

Create a middleware and pass it to the createStore function from Redux. Then you create a root epic that combines all your epics and call epicMiddleware.run() with the rootEpic.

import { createStore, compose, applyMiddleware } from 'redux';
import { createEpicMiddleware } from 'redux-observable';
import { combineEpics } from 'redux-observable';
import  { epicA } from './epicA';
import  { epicB } from './epicB';

export const rootEpic = combineEpics(
  epicA,
  epicB
);

const epicMiddleware = createEpicMiddleware();

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

export default function configureStore() {
  const store = createStore(
    rootReducer,
    composeEnhancers(
...

Continue reading →


Creating Your Menu

If you’ve ever hired anyone, then you probably know that there’s a whole range of questions spinning around in their head: Can I trust this person? How much will this cost me? What does the process look like? What do I even need? What if the scope spirals out of control and I waste my precious budget with the wrong person?

Creating a menu of your freelancing services is a painless way of offering a fixed-price service with a pre-defined process. You let people know exactly what they’re getting and how much it will cost from the get-go.

Besides making you easy to hire, giving people clear options up front eliminates the need for proposals. When you package up your service, you’re defining what the deliverables are, what you’ll do, what the price will be, and what the scope of work will cover. There is no need for back and forth, you have already boiled everything down to a simple...

Continue reading →


On Specialising as a Freelancer

The instinctive thing to do when you start looking for work is to go out and try to find as many new clients as you can. This seems like the obvious things to do, because - what else could you do?

Finding clients by word of mouth is largely down to figuring out who you are in the best position to serve. The idea is to figure out who the right kind of clients for you is, and then aim to do as much work as possible with them over time.

Look, finding new clients is a lot of work and can be expensive depending on how you do it. More it takes up a lot of time that you are not being paid for.

Working with new clients also means building a relationship from scratch, establishing expectations, and understanding how you both like to work. You end up spending a lot of time fine-tuning these nuances.

When you work with repeat clients, of clients referred to you by your repeat clients, you...

Continue reading →


An Unusual Guide To Professional Networking

Unfortunately, the most qualified person in the room doesn’t always get the job. Qualifying for any job means the position has to exist. This implies that a company had to advertise for that position. Applicants apply. Job interviews begin and somebody gets picked. People do get jobs this way, but it’s not the way most jobs get filled because most jobs never get advertised.

The informal job market is made up of all jobs that are not filled through formal advertisements. Usually, a position needs filling, and an employee knows somebody who’s qualified. Other times, a team wants someone specific to join them, and they create a position for that person out of thin air.

CNN, CBS, and NPR estimate over 80% of the jobs in America get filled informally. There is debate over exact numbers but the reality is likely more skewed in countries where application procedures are less formalized.

...

Continue reading →


Determining Our Usage Interval

I want to know how often I can expect people to use my app. I want this understanding to be derived from actual data, as opposed to my best guess of what I think is ‘normal’.

Once I’ve established a baseline for how often the majority of people have meaningful interactions with the app, then I have a clear benchmark to help people get to with my onboarding efforts.

I intend to plot my usage interval in Amplitude since it’s a tool designed specifically for this.

This means:

  1. Signing up to segment and Amplitude. Adding a tracking snipper to your app so that you can capture events. A connecting segment to Amplitude. They have a nifty little debugging tab so that you can make sure events are getting to Amplitude.
  2. Tracking incoming users. This means figuring where in your authentication flow you can send an event with basic user data to establish who you are tracking.
  3. Tracking your...

Continue reading →