Skip to main content

Events

Events are how the map tells your page what happened, whether the visitor caused it or you did.

Examples use a demonstration campus. Every snippet on this site addresses ucba, a publicly available campus with the building muntz-hall and the room 170. Substitute your own campus slug once you have one. Slugs for your campus are listed in your Waylocate console, and the addressing rules are in the reference grammar.

Subscribing

const unsubscribe = map.on("selection.changed", (payload, meta) => {
console.log(payload.room, meta.source);
});

unsubscribe();

map.on() returns its own unsubscribe function. map.off(name, handler) does the same thing if you prefer to keep the handler reference.

In TypeScript, the payload type is inferred from the event name. Names the SDK does not know still work and yield unknown, which is what allows an older SDK build to keep receiving events added after it shipped.

A handler that throws does not affect other handlers, and does not surface inside the message listener.

Event meta

Every handler receives a second argument.

interface EventMeta {
source?: "user" | "host" | "system";
at: number;
}
SourceMeaning
userA visitor gesture in the map
hostA command your page sent
systemThe map's own behaviour, such as framing a newly selected building

Checking meta.source === "user" is the standard way to avoid reacting to the echo of your own commands, which would otherwise produce a feedback loop in any page that both sends commands and updates its state from events.

at is the timestamp at which your page received the event.

Catalogue

EventPayloadFires when
selection.changed{ building, floor, room }The selected building, floor, or room changes
directions.changedDirectionsState | nullA route is drawn, updated, or cleared
state.changedMapStateAny state change, as a full snapshot
map.loadedMapStateThe campus data has finished loading
map.error{ code, message }The map failed at something it was doing
expand.requested{ url }The visitor asked to open the full map
camera.changedCameraPositionContinuously during camera motion, at about 10 Hz
camera.idleCameraPositionOnce, after camera motion settles
camera.pathEnded{ reason }Scripted camera playback finishes

map.ready also exists on the wire, but the SDK consumes it to complete the handshake. Its contents are on the handle as campus, protocol, capabilities, and build.

Opt-in events

camera.changed and camera.idle are not sent unless a host asks for them, because a single pan gesture would otherwise produce hundreds of messages.

You do not have to manage that. map.on() sends the subscription when the first handler for an event is added and withdraws it when the last one is removed. The distinction between opt-in and default events is not something you need to keep track of.

expand.requested

The map's expand button opens the full map in a new tab. When your page has a handler for expand.requested, the map emits the event and does not open the tab, handing you the decision.

map.on("expand.requested", ({ url }) => {
openInModal(url);
});

Without a handler, the button behaves as it does on the standalone map. This avoids the failure where a host enables the expand control and forgets to listen, leaving the visitor with a button that does nothing.

About camera.idle

camera.idle is derived from the end of a movement plus a short settle window, rather than from the rendering library's own idle signal. The map's overlay layers request repaints while animations are live, and on a busy campus the library's idle event may never fire at all. A host waiting on it would hang.

Next