DEV Community

Ansh Saini
Ansh Saini

Posted on

3 1

Why you cannot pass location.reload as an argument

Let's say we have a function named blockUser which looks something like this

const blockUser = (afterBlock = window.location.reload) => {
  // Some code to block the user
  afterBlock()
}
Enter fullscreen mode Exit fullscreen mode

The interesting thing about this function is the afterBlock argument which defaults to window.location.reload. We basically want to reload the page after a user is blocked. But not always. Hence, the argument.

Lets use our pretty function:

blockUser()
Enter fullscreen mode Exit fullscreen mode

Oops

Illegal Invocation Error from Chrome
Firefox gives us a more descriptive error.
Illegal Invocation Error from Firefox

Why does this happen?

location.reload requires that this should point to location. When we are using javascript functions, this is bound to the scope from which the function was called.
if we call window.location.reload() directly, then the reload function is getting called through the location object. But lets say we do:

const test = window.location.reload
test()
Enter fullscreen mode Exit fullscreen mode

Illegal Invocation Error from Chrome

We will still get the same error.
Let's try to create our own reload function to see what's going on.

const fakeWindow = { location: { reload: function() { console.log(this) } } }
fakeWindow.location.reload()

// Re-assigning
let test = fakeWindow.location.reload
test()
Enter fullscreen mode Exit fullscreen mode

Custom reload function

Whoa, looks like this is not the same anymore when we assign the reload function to a variable. If you remember the Firefox error, the reload function requires that it should be called from the context of Location. When we assign it to a variable, it gets called from the context of Window.

How can we fix it?

The fix is pretty simple, you can just wrap a function around your re-assignment.

const blockUser = (afterBlock = () => window.location.reload()) => {
  // Some code to block the user
  afterBlock()
}
const test = () => window.location.reload()
Enter fullscreen mode Exit fullscreen mode

It works now! ๐Ÿ˜„

Bonus

Can you guess what will happen if we defined our fakeWindow object a little differently?

const fakeWindow = { location: { reload: () => { console.log(this) } } }
fakeWindow.location.reload()
Enter fullscreen mode Exit fullscreen mode

Have you ever come across this problem in a real project? Drop your thoughts and experiences in the comments. Don't forget to answer the question in Bonus section :)

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy ๐ŸŽ–๏ธ โ€ข โ€ข Edited

Or just make a function with this pointing to location:

afterBlock = window.location.reload.bind(window.location)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
anshsaini profile image
Ansh Saini โ€ข

Yes, this is also a good alternative

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

๐Ÿ‘‹ Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Communityโ€”every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple โ€œthank youโ€ goes a long wayโ€”express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay