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.