Debugging JS in the browser with breakOn
Tags: javascript, es6, debugging, webdev
Published: 2019-03-30 05:51:04

---
title: Debugging JS in the browser with breakOn
published: true
description: 
tags: javascript, ES6, debugging, webdev
---

TLDR: See [breakOn](https://github.com/paulirish/break-on-access)

### The Problem
Last week, I came across a strange bug where an object's property was randomly changing in-between network calls. This particular object was being referenced in multiple places and I was having a hard time figuring out where exactly the change was happening. After spending some time debugging with `debugger` statements and chrome's devTools, I realized what I basically needed was to see a log of the objects modifications. 

### Option #1: Object.Observe
JS had a useful utility function `Object.observe(obj, handler)` method which track all actions on an object. So for this case I could just do a,
 
 ```javascript
 Object.observe(obj, ...console.log);
 ```
 and it would print out all the information for `obj`'s props
 
Unfortunately this method has been deprecated and couldn't be enabled (easily) in chrome or any other modern browsers that I've tested. 

### Option #2: ES6 Proxy
The new `Proxy` in ES6 in recommended as the alternative to the old `Object.observe`, although they aren't functionally equivalent. Using proxy classes we can create a observer like so,
```javascript
const observe = objToObserve => {
  const handler = {
    get: (obj, prop) => {
      console.log(`GET ${prop} = ${obj[prop]}`);
      return obj[prop];
    },
    set: (obj, prop, value) => {
      console.log(`SET ${prop} = ${value}`);
      obj[prop] = value;
      return true;
    }
  };
  return new Proxy(objToObserve, handler);
};
```

and now we can do
```javascript
let me = { name: "John" };
me = observe(me);

me.name = "Jake"; 			// Console output: SET name = Jake
me.age = 12; 				// Console output: SET age = 12

if (me.age > 10) { 			// Console output: GET age = 12
  console.log("You're old enough to ride a bike!");
}
```

The problem here is that `observe` creates a new object, so we need to modify the original object reference wherever we want to track the changes. Which isn't much of a problem, but having to do that means that we need to be aware of where the reference is being initialized and modify it appropriately. This can also lead to problems if you're using `const` to initialize your variables. So although it would work,  I was still not satisfied with this solution. 

### Option #3: breakOn
Enter [breakOn](https://github.com/paulirish/break-on-access). 
I came across breakOn through stackoverflow and it's pretty much exactly what I need. breakOn is a single-file library that has a single method, `breakOn`. `breakOn` can set a breakpoint whenever a property changes ( or is accessed! ). 
Here's how you use it,

```javascript
const me = {name: 'John'}; // We can use const

breakOn(me, 'name');

person.me = "Jake"; // Breakpoint is triggered 

```

Now you can use [add this as a snippet on chrome](https://developers.google.com/web/tools/chrome-devtools/snippets), and you can use it from chrome's devTool console on any site!

Unfortunately what I needed was logs, not really a breakpoint but the good news is that the function can easily be modified to do a console log (or any other action) instead of a break, which I ended up doing. 

breakOn was exactly what I was looking for and although the code is a bit old now (2013'ish), and there are a lot of things that wouldn't be done the way it's done if it was written now, it served my use-case well and hopefully it'll come in handy for you too!