Events
Events are how the map tells your page what happened, whether the visitor caused it or you did.
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;
}
| Source | Meaning |
|---|---|
user | A visitor gesture in the map |
host | A command your page sent |
system | The 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
| Event | Payload | Fires when |
|---|---|---|
selection.changed | { building, floor, room } | The selected building, floor, or room changes |
directions.changed | DirectionsState | null | A route is drawn, updated, or cleared |
state.changed | MapState | Any state change, as a full snapshot |
map.loaded | MapState | The 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.changed | CameraPosition | Continuously during camera motion, at about 10 Hz |
camera.idle | CameraPosition | Once, 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
- Errors for failure handling.
- Protocol events for the wire-level catalogue.