Skip to content

Instantly share code, notes, and snippets.

@cwayfinder
Last active August 11, 2018 07:35
Show Gist options
  • Save cwayfinder/26816c138f6bdfb06eaba85f0e270dc0 to your computer and use it in GitHub Desktop.
Save cwayfinder/26816c138f6bdfb06eaba85f0e270dc0 to your computer and use it in GitHub Desktop.

Analytics integration for ngrx/store

Introduction

If you're using ngrx/store to manage your app's state, you can use this to tap into your dispatched actions and map them to events that are consumable by an analytics service (e.g. Google Analytics). With this approach your entire global state life-cycle becomes trackable.

Redux Beacon Diagram

Examples

We have to create a event creator - pure function quite similar to a reducer, except returning analytics event definition instead of a new state

export const bookingEventCreator = (action: typeof All, state: AppState): EventDefinition => {
  switch (action.type) {
    case AddBookingSuccess.type:
      return {
        event: 'domEvent',
        id: action.type,
        data: {
          bookingRef: action.payload.bookingRef,
          userEmail: state.account.email,
        },
      };

    case AddBookingFail.type:
      return {
        event: 'domEvent',
        id: action.type,
        data: {
          ...action.payload,
        },
      };
  }

  return undefined;
};

This can be rewritten using the eventCreator and on functions in ts-action manner.

export const bookingEventCreator = eventCreator<AppState>([
  on(AddBookingSuccess, (action, state) => ({
    event: 'domEvent',
    id: action.type,
    data: {
      bookingRef: action.payload.bookingRef,
      userEmail: state.account.email,
    },
  })),
  on(AddBookingFail, (action) => ({
    event: 'domEvent',
    id: action.type,
    data: {
      ...action.payload,
    },
  })),
]);

These event definitions have some common part. This boilerplate can be removed by using the ngrx helper.

export const bookingEventCreator = eventCreator<AppState>([
  on(AddBookingSuccess, ngrx(({ payload }, state) => ({
    bookingRef: payload.bookingRef,
    userEmail: state.account.email,
  }))),
  on(AddBookingFail, ngrx(({ payload }) => ({ ...payload }))),
]);

If you just want to propagate the ngrx action's payload to the analytics event, use the ngrxPayload helper

export const bookingEventCreator = eventCreator<AppState>([
  on(AddBookingSuccess, ngrx(({ payload }, state) => ({
    bookingRef: payload.bookingRef,
    userEmail: state.account.email,
  }))),
  on(AddBookingFail, ngrxPayload()),
]);

Usage

  • Step 1. Write the event creator function (or a few) (see examples above)

  • Step 2. Specify them in meta reducer

{
  provide: META_REDUCERS,
  useFactory: () => {
    return [createAnalyticsMetaReducer<AppState>([bookingEventCreator])];
  },
}
@cwayfinder
Copy link
Author

I don't want to see this rubbish in the ngrx action list

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment