DEV Community

Cover image for Control the function internals with callbacks
Taha Shashtari
Taha Shashtari

Posted on • Edited on • Originally published at tahazsh.com

Control the function internals with callbacks

There are many uses for callbacks in JavaScript. But the one I really like—and not often talked about—is modifying the behavior of some internal parts of that function.

Let me show you an example.

Example

Let's say you have a function that fetches and returns some post data.

function getPostById(id) {
  // I'm going to return a literal object here,
  // but imagine it's fetching the post from somewhere
  return {
    title: 'Post Title',
    date: new Date().toString(),
    tags: ['tag1', 'tag2']
  }
}
Enter fullscreen mode Exit fullscreen mode

I'm going to focus on the date field for this example.

The date returned here is formatted using the toString method. If I want to change it to a different format, I have to parse that string into a date object, and then format it however I want.

But wouldn't it be nice if I can specify the formatting code directly in the function without modifying the function code?

A great thing about JavaScript is that it has first-class functions. This means I can pass functions as values to another functions—we call them callbacks.

So, I can modify the function above to move the formatting code into a callback instead of hardcoding it in the body of the function.

function getPostById(id, fnDateFormatter = (date) => date.toString()) {
  return {
    title: 'Post Title',
    date: fnDateFormatter(new Date()),
    tags: ['tag1', 'tag2']
  }
}
Enter fullscreen mode Exit fullscreen mode

If you run the code above, it will work exactly as the previous one. The difference here is that I format new Date() using the fnDateFormatter callback. Also note how I can specify a default callback in the parameters directly—isn't JavaScript great?

Because fnDateFormatter is a parameter that accepts a function as a value, I can pass it any other function I want when calling it.

function myDateFormatter(date) {
  return date.toLocaleDateString(
    'en-us',
    {
      weekday: 'long',
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    }
  )
}

const testPostWithDefaultFormatter = getPostById(1)
const testPostWithMyFormatter = getPostById(1, myDateFormatter)
Enter fullscreen mode Exit fullscreen mode

I called the function twice: one with the default formatter, and one with a custom formatter. Note how I didn't need to touch the original function code in either one.

Top comments (1)

Collapse
 
ant_f_dev profile image
Anthony Fung

Nice tip!

I've used a few JS UI component libraries, and some of them let you pass in functions that e.g. control the formatting of how data is presented. It's a very similar idea and agree that it can be really powerful as the caller get to specify exactly how the data is presented/returned.