Skip to content Skip to sidebar Skip to footer

Custom Attribute Attached Event Too Early?

The custom component I've created a custom component for the navigation of my app. It consists of an ul element and all its li elements are dynamically created based on the items i

Solution 1:

Allow me take away your misconception about the TaskQueue.

Your idea of moving things in time causing maintenance issues would certainly apply to using setTimeout() because that incurs an actual delay, and forces execution onto the next event loop. queueTask() is more or less the same thing (it uses setTimeout() internally).

However, the TaskQueue's queueMicroTask() method works very differently.

When you call queueMicroTask(), unlike queueTask() and setTimeout(), the task is scheduled for immediate execution on the same event loop. This is a very robust mechanism with a guaranteed execution order, and it's generally considered good practice to use it within attached() before doing any DOM manipulation.

In fact, queueMicroTask() is used internally by Aurelia in various places (mostly in binding and templating-resources). Two notable places are:

  • Property- and collection observers use it to "delay" notifying subscribers until all other bindings have completed their internal updating work
  • The repeat attribute uses it to set an ignoreMutations flag (and unset it after the queue is flushed) to prevent infinite recursion while updating its inner collection

You can generally consider there to be two "phases" to the bind() and attached() hooks: a non-queued, and a queued phase. The queued phase is when components do work that relies on the whole component graph to first be done with some other (usually recursive) process.

queueMicroTask()does not delay execution, just pushes it to the end of the call stack

It's the functional equivalent of passing the function as a callback to the end of the call stack, but saves you the trouble of writing the spaghetti code required to locate that last call and wire it all up. It's super clean.

all its li elements are dynamically created based on the items in the router's navigation list. This is happening in the attached event of the component

See, whenever you create anything during attached(), you can't rely on that thing being there during another component's attached() as this depends on the order of compilation/composition. That's an internal matter. This is especially true for custom attributes. Custom attributes (particularly those in style libraries) use the TaskQueue all over the place because it's the only way they can rely on the DOM being done.

Using queueMicroTask() here will guarantee two things:

  • It's executed when aurelia is completely done with the "first pass" of attacheds and rendering
  • It's executed immediately when aurelia is done with that - not even a microsecond delayed.

The best (and perhaps only correct) way to address this is indeed by using the TaskQueue - I promise :)

Post a Comment for "Custom Attribute Attached Event Too Early?"