This is the documentation of version 0.63.0. Go to the latest version, 1.0.0-rc.5.
TomTom Maps for JavaScript
    Preparing search index...

    Class UserEventsWithStates<T>

    A named events scope of a module that draws its own data: the UserEvents of one part of what the module shows, plus the event states of those features.

    The module's own putEventState, cleanEventState, cleanEventStates and getEventStates act on the features its show takes; a scope's act on the scope's features alone, by the ids its handlers receive — routing.events.waypoints on the waypoints, custom.events.<source> on one source. A UserEvents.where narrowing returns plain UserEvents: a state belongs to a feature, not to a predicate over features.

    routing.events.waypoints.putEventState({ id: waypoint.id, state: 'click' });
    const { hover: hoveredStops = [] } = routing.events.waypoints.getEventStates();

    Type Parameters

    Hierarchy (View Summary)

    Index
    • Remove all event handlers for a specific event type.

      Unregisters the callback function for the specified event type, stopping further event notifications. This is important for cleanup to prevent memory leaks and unwanted behavior.

      Parameters

      • type: EventType

        The type of event to stop listening for

      Returns void

      Cleanup Behavior:

      • Removes all handlers for the specified event type — to remove a single handler, call the unsubscribe function returned by on
      • Other event types remain active
      • Resets cursor behavior for this module
      • Safe to call multiple times (no error if no handler exists)
      • Does not affect other modules' event handlers

      When to Use:

      • Component unmounting/cleanup
      • Switching between interaction modes
      • Temporarily disabling interactions
      • Replacing an existing handler (call off() then on())

      Best Practices:

      • Always clean up event handlers when component unmounts
      • Remove handlers before removing features from the map
      • Use framework lifecycle hooks for automatic cleanup
      // Remove click handlers
      module.events.off('click');

      // Remove all handlers
      module.events.off('click');
      module.events.off('hover');
      module.events.off('long-hover');
      module.events.off('contextmenu');
      // React component cleanup
      useEffect(() => {
      const pois = map.pois();

      pois.events.on('click', handlePoiClick);
      pois.events.on('hover', handlePoiHover);

      return () => {
      // Cleanup on unmount
      pois.events.off('click');
      pois.events.off('hover');
      };
      }, [map]);
      // Replace handler
      module.events.off('click'); // Remove old handler
      module.events.on('click', newHandler); // Add new handler

      // Disable interactions temporarily
      const savedHandler = currentHandler;
      module.events.off('click'); // Disable
      // ... later ...
      module.events.on('click', savedHandler); // Re-enable
    • Register an event handler for user interactions with map features.

      Attaches a callback function that will be invoked when users interact with features in this module (e.g., clicking on a POI, hovering over a route).

      Parameters

      • type: EventType

        The type of event to listen for (click, contextmenu, hover, long-hover)

      • handler: UserEventHandler<T>

        Callback function invoked when the event occurs

      Returns () => void

      An unsubscribe function that removes the handler registered by this call.

      Handler Parameters:

      • feature: The primary feature that triggered the event
      • lngLat: Geographic coordinates [longitude, latitude] of the event
      • features: The features from this module at the event location, de-duplicated (for overlapping features within the module). To inspect features across all modules, query map.mapLibreMap.queryRenderedFeatures(...) directly — see UserEventHandler.

      Behavior:

      • Multiple handlers per event type are supported — each on() adds a handler (it does not replace existing ones) and all of them fire. To remove one, call the unsubscribe this returns; to clear them all, use off(type).
      • Handlers are preserved across map style changes
      • Cursor automatically changes to pointer on hover
      • Events respect module visibility (hidden features don't trigger events)

      Performance:

      • Hover events use spatial indexing for fast lookup
      • Long-hover has configurable delay to prevent accidental triggers
      • Event handlers should be lightweight to maintain smooth interaction
      // Basic click handler
      module.events.on('click', (feature, lngLat, features) => {
      console.log('Clicked feature:', feature.properties);
      console.log('Location:', lngLat);
      console.log('All features here:', features.length);
      });

      // Hover with tooltip
      module.events.on('hover', (feature) => {
      const name = feature.properties.name || 'Unnamed';
      tooltip.show(name);
      });

      // Long-hover for detailed preview
      module.events.on('long-hover', (feature) => {
      // Only triggered after hovering for 300-800ms
      loadPreview(feature.properties.id);
      });

      // Right-click context menu
      module.events.on('contextmenu', (feature, lngLat) => {
      event.preventDefault(); // Prevent browser context menu
      showCustomMenu(lngLat, feature);
      });
      // Route-specific handlers
      const routing = map.routing();

      // Handle route line clicks
      routing.events.mainLines.on('click', (route) => {
      highlightRoute(route.properties.routeID);
      showRouteSummary(route.properties.summary);
      });

      // Handle waypoint interactions
      routing.events.waypoints.on('hover', (waypoint) => {
      const index = waypoint.properties.index;
      showTooltip(`Stop ${index + 1}`);
      });
    • Narrows these events to part of what they cover, returning a UserEvents over just that part.

      Two things can be narrowed. A feature predicate keeps only the features you care about — available on every module, since only the module's own data can tell a major incident from a minor one. A layer scope keeps only part of the map's layers; the SDK offers this where a stable, typed vocabulary for those layers exists, which today means BaseMapModule's layer groups.

      A new instance, rather than this one narrowed in place: callers hold events and narrow it more than once, and mutating would make the second where() mean "first AND second" while leaving the surface it came from silently scoped — and its config overridden.

      Narrowing on both axes is one call, not two — BaseMapModule's scope object takes a features predicate alongside its layerGroups. A further where() does intersect with this one, but two feature predicates read better as a single a(f) && b(f).

      Parameters

      • scope: (feature: T) => boolean

        See EventScope — a predicate over this scope's feature type, or, where the module supports one, a scope object such as { layerGroups }.

      • Optionalconfig: EventHandlerConfig

        Event configuration for handlers registered through the returned instance. Each scope can carry its own, which is how two parts of one module get different hover cursors. Defaults to the configuration this instance already uses.

      Returns UserEvents<T, never>

      // Feature scope: only major incidents are clickable.
      trafficIncidents.events.where((incident) => incident.properties.magnitude === 'major')
      .on('click', showIncidentDetails);

      // Layer scope with its own cursor, on the base map.
      baseMap.events
      .where({ layerGroups: { show: 'only', values: ['roadLabels'] } }, { cursorOnHover: 'pointer' })
      .on('click', showRoadName);

      // A named scope, narrowed by a predicate.
      routing.events.tunnels.where((section) => section.properties.lengthInMeters > 500)
      .on('click', showLongTunnel);