Dev
Synchronous Timing Hell

HELL YES! It was worth staying up most of the night to learn this and find the solution. This side quest was epic! But I rolled a natural 20 and slayed the dragon. I'm working on a form at work in @filamentphp which is a TALL stack app. I have a field, serial number. When the user updates that field I was tryin to use the afterStateUpdated() method, which accepts a callback.

The callback pulls data from an API and updates 4 other selects. It's a greedy little API and takes several seconds to return. I wanted to let the user know that it is actually working so I wanted to throw up a modal with a spinner to show them that it's doing it's job.

The first trick was figuring out how to properly dispatch a modal in the Filament context. Of course that turned out easy, I had it working almost immediately. But I was tricked! I thought it wasn't working for nearly the entire day and night. Why you ask? Synchronicity.

In an event like this, the callback as to execute ALL instructions within it before it then it's bubble pops releasing all the contents all over your dom. So when the afterStateUpdated() event fired for my serial number field the callback created it's pocket dimension, issued the open modal event, did the api call and then issued the close modal event. And then like the big bang, this little pocket dimension popped and the contents spilled out into our universe (the dom) essentially firing both events for the modal at the same time so I never saw it.

While I was debugging I introduced a sleep and noticed the pop up was happening. After a serious round of trial and error I realized what was happening and tried a number of ways to solve it.

The solution I came up with was to use javascript to launch the modal. I knew if I could do it with javascript then the synchronous nature of php's closure would work for closing it since the close event is dispatched at the end of the process, after the api call. I needed to add a function in the js for this form and bind it to the element with Filament's extraAttributes() method. Added an onChange event that calls my custom function to launch the modal. Then it's standard from there on.

This was a tough one and I loved every second of it. I would love to have solved it faster but this forced me to really learn what was happening and understand it more deeply. I was able to leverage javascript's asynchronous nature to launch the modal and then let php take over for the synchronous bubble which produced the blocking behavior I wanted for this user interaction.

I just need to clean it up and now I can finish the actual task I was workin on. This was a side quest just to improve user experience. I think @thdxr might approve of that level of attention to detail. Or he'll call me something mean, it's Dax.

Of course, I could have way over complicated all this. The solution was quite simple once I understood what was happening. I'm not big on front end, so understanding how timing works in that realm is still new to me. And I want to get really good at it and I think this helps.

Is there a better way to solve this?

No comments yet…

avatar
You can use Markdown
No results