JavaScript debug output helper for expression-body lambdas

Sometimes I don’t fancy debugging a piece of code in the browser. I mean that as in “use the debugger” – I’d much rather see some log output. This can be more useful than step-by-step debugging because the program flow is not interrupted, which can cause strange behavior in its own right, and because log output makes it easier to see how values go in and out of functions as the program runs through its flow.

Since I prefer writing code in a functional style, I often have the problem that it’s not easy to quickly insert console.log calls. For instance I was just looking at this piece of code:

const validate = buildValidate({
  name: value => (value && value.length >= 5 ? 'success' : 'error')
});

In order to insert a log output statement manually, I would need to add braces and a return statement first, perhaps ending up with something like this:

const validate = buildValidate({
  name: value => {
    console.log('validateName: ', value);
    return (value && value.length >= 5 ? 'success' : 'error');
  }
});

And of course, when I’m done, I’d have to remove the extra elements again. This is tedious and error-prone. I googled for magical solutions and didn’t find any (please let me know if you’re aware of something I missed!), so I ended up writing my own little helper:

const debug = (id, f, options = {}) => {
  const output = options.output || console.log;
  const processResult = options.processResult || (result => result);
  const processArgs = options.processArgs || (args => args);
  return (...args) => {
    output(`DEBUG(${id}): `, processArgs(args));
    const result = f(...args);
    output(`DEBUG(${id}/result): `, processResult(result));
    return result;
  };
};

With the help of this function, I can now “instrument” my original code by simply wrapping my original lambda in a call to debug:

const validate = buildValidate({
  name: debug(
    'validateName',
    value => (value && value.length >= 5 ? 'success' : 'error'))
});

This change is easier to make: with the exception of adding parens for the call to debug, there is no structural change required (such as adding braces).

I’m sure the solution isn’t perfect for all use cases. I’ve added a few options that would allow processing of data before it’s logged — useful for instance when the result is a Promise.

As a quick hack, this seems a nice helper for my perhaps peculiar debugging habits!

3 Comments on JavaScript debug output helper for expression-body lambdas

  1. Hi.
    Another option that I use is add breakpoint with console.log(value1, value2). Of couse it not a complete replacement for the proposed solution, but in some cases this is enough.

    Like

  2. True, though I have to say I find it quite hard to reliably set a breakpoint somewhere in a functional expression. The Chrome debugger seems to work differently, for instance, when I debug with or without source maps… it’s usually possible to make it do what I want, but it can be fiddly.

    Like

  3. Meanwhile I found that my helper function works really well even in complicated cases. For instance I might have a functional React component, using recompose and styled-components:

    const LocationPanel = setPropTypes({
      panelHeaderText: PropTypes.string.isRequired,
      ...
    })(styled(
      ({
        panelHeaderText,
        children,
        className,
        ...
      }) => (
        <Panel className={className} header={panelHeaderText}>
          ...
        </Panel>
      )
    )`
      height: 500px;
    `);
    

    I can insert my debug output helper into this expression to see exactly what the component receives at a certain point:

    const LocationPanel = setPropTypes({
      panelHeaderText: PropTypes.string.isRequired,
      ...
    })(debug(styled(
      ({
        panelHeaderText,
        children,
        className,
        ...
      }) => (
        <Panel className={className} header={panelHeaderText}>
          ...
        </Panel>
      )
    )`
      height: 500px;
    `));
    

    This helper has turned out to be much more useful than I originally thought. I’m surprised I wasn’t able to find this kind of thing as an existing npm package. Perhaps I should create one.

    Like

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s