0

I have code like this about five times in my project, and I know I'm going to have it more often than that:

this.messageHandler = ({ data, origin }) => {
    if (origin === window.location.origin) {
        if (
            data.listener === this.listener &&
            data.event === 'rowclick'
        ) {
            this.recordId = data.datarow;
        }
    }
};
window.addEventListener('message', this.messageHandler);

Each time here are the only differences:

  • this.listener has a unique value for each class.
  • this.recordId is different each time, it might be this.userId or this.accountId, but so far I'm always setting a property that represents a record's ID.

I'd like to create a function that builds this function. I think this is possible in JavaScript. I seem to remember seeing information on how to do it in one of the many JS resources I used when learning the language. But I can't find the information now.

Ideally, I'd replace the above with something like this:

window.addEventListender('message', generateHandler(this.listener, (datarow) => {
    this.recordId = datarow;
});

How can I do this in JavaScript?

3
  • 2
    You don't need to do anything particular, just write a function that defines a function then returns it. Commented Oct 24, 2021 at 21:30
  • Is your concern about what this refers to? Perhaps looking at closures might help but I wasn't sure if that's what you were after. Commented Oct 24, 2021 at 21:35
  • 1
    Notice how you just assigned a function to the variable this.messageHandler? Nothing stops you from writing all of that inside another function that simply returns this.messageHandler thus you would have a function that returns another function. Functions are first class members in JavaScript... developintelligence.com/blog/2016/10/… Commented Oct 24, 2021 at 21:35

2 Answers 2

3

I appreciate the tips in the comments, they helped quite a lot. This is what I ended up writing:

const generateMessageHandler = (listener, callback) => {
    return ({ data, origin }) => {
        if (
            origin === window.location.origin &&
            data.listener === listener &&
            data.event === 'rowclick'
        ) {
            callback(data.datarow);
        }
    };
}

And then calling it with this:

window.addEventListener(
    'message',
    generateMessageHandler(this.rowClickListenerName, (datarow) => {
        this.recordId = datarow;
    })
);

I think I had all the pieces to start with, but something was blocking figuring out the final implementation until the commenters started talking about functions returning functions.

Sign up to request clarification or add additional context in comments.

2 Comments

"until the commenters started talking about functions returning functions." - wait, didn't you talk about just that in the title of your question already? :D
Yea, but for some reason the way to build it wasn't clear at the time. This is the first time I've done this, so knowing it was possible and knowing how to do it weren't yet the same thing.
-1

You can certainly return function inside a function in JavaScript, but what's the point in your case?

You can just set the handler to an anonymous function calling your function:

window.addEventListener('message', () => yourFunction(arg1, arg2, arg3));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.