Skip to content

[Feature ] Add "subscribe" method to EventDispatcher class and to lizMap object#6414

Closed
mind84 wants to merge 3 commits into3liz:masterfrom
mind84:uiready
Closed

[Feature ] Add "subscribe" method to EventDispatcher class and to lizMap object#6414
mind84 wants to merge 3 commits into3liz:masterfrom
mind84:uiready

Conversation

@mind84
Copy link
Copy Markdown
Collaborator

@mind84 mind84 commented Jan 9, 2026

There is currently no guarantee that the uicreated event will be fired after all Lizmap HTML components have been fully loaded. This makes uicreated event not fully reliable when trying to interact with other UI components (print, navbar, selectionTool and so on) via js custom.

IMHO uicreated should be renamed, but that requires some refactoring of some legacy code and I'm not really sure if it's worth it, especially considering that lizMap.events relies on OL2, which I imagine will be removed as a dependency sooner or later. On top of that, uicreated is a key event deeply involved in the application startup.
For those reasons I would not touch it.

/** DEPRECATED**/
Instead, I would introduce a new event called uiready which fires after all custom HTML component/modules have been defined and initialized (which happens synchronously in defineCustomElements function).
/** DEPRECATED**/

EDIT:

Following @mdouchin's comment #6414 (comment), I tried to figure out how to include the proposal made in #6420 without adding external dependencies.

Far from replicating rxjs's Observable pattern (which is probably a bit overkill), I've added a few changes that should fix some problems:

  1. Implementation of the EventDispatcher class. I added the subscribe method, which allows listeners to be notified even if they were defined after the event was emitted. This is primarily to solve the various problems caused by parallel loading of two js files that are heavily dependent on each other (the Lizmap class and the legacy map code).
  2. Based on step 1, I refactored the application initialization, separating the asynchronous part of the code (XHR to load functionality and configuration) into a dedicated asynchronous method. This should help organize code execution better. Initialization is now based on the EventDispatcher class and no longer on the lizMap.events property. This required adding new events handled by the EventDispatcher class, I have proposed some names for these events but they can be changed.
  3. I tried to make the introduction of external js more robust by exposing a dedicated method in the lizMap singleton. The concept is very similar to the previous uiready event, except that it relies on the subscribe method introduced in the EventDispatcher class. Example:
       // my_extranl_js.js
       
       lizMap.subscribe(()=>{
           // do stuff with interface
       },'lizmap.uicreated')
    The subscribe method makes loading the external js practically independent of application startup; the method's callback is called only when the application is fully loaded. I say "practically" because there's actually no sequential control over how the js are loaded since they're deferred, so there's a theoretical possibility that they'll be loaded before the lizmap singleton, although in practice this doesn't happen. This should make it easier to add custom js.
    For now, you can only subscribe to the lizmap.uicreated event; the old event has been kept for backwards.compatibility.
  4. Added some js test for external js loading.

I hope I didn't mess up the .gitignore 😄

Bakport to 3.9 and 3.10, if possible.

Thanks!

Funded by Faunalia

@github-actions github-actions Bot added this to the 3.11.0 milestone Jan 9, 2026
@mdouchin
Copy link
Copy Markdown
Collaborator

mdouchin commented Jan 9, 2026

Love the idea. We were indeed struggling lately with browser updates (chromium/edge) which will not load files in the correct order depending on the cache.

We were discussing this matter in the team. Happy to discuss here the best approach.

At present, only uggly workaround will help to be sure elements are ready, such as:

function loadTooltipOnStart() {
	if (lizMap.mainLizmap.tooltip.activeLayerOrder == 0) return true;
	console.log('TOOLTIP - Load first layer on start');

	// Activate tooltip at startup - Load first layer on start
	lizMap.mainLizmap.tooltip.activate(0);
}
function waitForObject() {
	return new Promise((resolve, reject) => {
		const intervalId = setInterval(() => {
			if (lizMap && lizMap.mainLizmap && lizMap.mainLizmap.tooltip && lizMap.mainEventDispatcher) {
				clearInterval(intervalId);
				resolve(true);
			}
		}, 200); // Check every 200 milliseconds for availability of thatObject
	});
}
waitForObject().then((response) => {
	// console.log(response);
	loadTooltipOnStart();
});

cc @rldhont @nboisteault

@rldhont rldhont added javascript Pull requests that update Javascript code backport release_3_9 backport release_3_10 sponsored development This development has been funded labels Jan 9, 2026
@rldhont
Copy link
Copy Markdown
Collaborator

rldhont commented Jan 9, 2026

@mind84 your fix will help for some scripts.

@mind84
Copy link
Copy Markdown
Collaborator Author

mind84 commented Jan 9, 2026

@mdouchin

Observables could come in handy in these situations.

Something like this https://rxjs.dev/guide/observable

It is just an example of course!

@josemvm
Copy link
Copy Markdown
Collaborator

josemvm commented Jan 9, 2026

#5964 (comment)

@mind84 mind84 marked this pull request as draft January 18, 2026 10:12
@mdouchin mdouchin requested a review from rldhont January 19, 2026 07:42
@mind84 mind84 marked this pull request as ready for review January 19, 2026 07:44
@mind84 mind84 changed the title [Feature ] Add "uiready" event [Feature ] Add "subscribe" method to EventDispatcher class and lizMap object Jan 19, 2026
@mind84 mind84 changed the title [Feature ] Add "subscribe" method to EventDispatcher class and lizMap object [Feature ] Add "subscribe" method to EventDispatcher class and to lizMap object Jan 19, 2026
@rldhont
Copy link
Copy Markdown
Collaborator

rldhont commented Jan 19, 2026

Hi @mind84, thanks a lot for your great job !

Theses changes will not be backported to 3.9. Can you reopen a PR with the uiready event in the old way to be able to backport it to 3.9 ?

@mind84
Copy link
Copy Markdown
Collaborator Author

mind84 commented Jan 19, 2026

Hi @rldhont,

Hi @mind84, thanks a lot for your great job !

Theses changes will not be backported to 3.9. Can you reopen a PR with the uiready event in the old way to be able to backport it to 3.9 ?

It is fine to me! This however means that users have to edit their custom js twice between 3.9 and 3.10, since uiready event will be no longer available in 3.10.

@rldhont
Copy link
Copy Markdown
Collaborator

rldhont commented Jan 19, 2026

It is fine to me! This however means that users have to edit their custom js twice between 3.9 and 3.10, since uiready event will be no longer available in 3.10.

You are right, but JavaScript created already have to update their scripts for 3.9 if they need some elements provided by components.

@mind84
Copy link
Copy Markdown
Collaborator Author

mind84 commented Jan 19, 2026

@rldhont,

I created #6440 and #6441 to keep things tidy

Thanks!

@rldhont
Copy link
Copy Markdown
Collaborator

rldhont commented Jan 19, 2026

Thanks @mind84

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport release_3_9 backport release_3_10 javascript Pull requests that update Javascript code sponsored development This development has been funded

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants