Ask — Events
Run your own code when a question goes out, when its answer shows and finishes, and when the reader rates it.
The Ask workflow emits an event at each step of a question. Below we listen to
one, list the events a question goes through, and then look at the data
event, which tracks the response itself.
You need a working Ask page first. See Ask — Quick Start.
Listen to an event
Call on with the event name and a function. Set it on client.ui.asks, the
context, so follow-up answers emit to it too:
const off = client.ui.asks.on("done", ({ workflow }) => {
console.log("Answer done", workflow.questionId);
});
Each event on the context carries workflow, the Ask workflow that emitted it.
Its questionId is the question the event belongs to. For a follow-up, that
is different from client.ui.ask.questionId, the first question of the thread.
on returns a function. Call it to remove the listener:
off();
To listen to the first question only, call on on client.ui.ask. Events on
a single workflow do not carry workflow.
Lifecycle events
Each question goes through these events in order. Each one fires at most once for a question:
| Event | Fires when |
|---|---|
request | The SDK sends the question to Miso. payload is the request body. |
loading | The request is out, and the SDK waits for the answer. |
ready | The answer starts to show. |
blocked Since 1.13.0 | Miso withheld the answer, for example at a metering limit. blockedReason says why. |
done | The full answer is on screen. |
interrupt | A new question replaced this one before its answer finished. |
error | The question failed. |
finally | The question has ended, in any of the three ways above. |
A question always ends with one of done, interrupt and error, and then
with finally. Use finally for clean-up that has to run each time, such as
hiding a spinner of your own.
ready and done follow what is on screen. done fires when the
last word of the answer shows, which is after the last part of the response
arrives. To act on the response as it arrives, use the
data event.
Apart from request, these events carry:
| Property | What it holds |
|---|---|
session | The session of the question. A new question gets a new session. |
status | loading, ready or erroneous. |
ongoing | true while more of the answer is on the way. |
The SDK also emits answer-stage each time the progress label of the answer
changes, with the label in answer_stage. Use it for display only. The labels
change without notice, so do not branch on them. See
Answer API.
Feedback event
feedback fires when the reader clicks Helpful or Not helpful under
an answer:
client.ui.asks.on("feedback", ({ workflow, value, unselected }) => {
if (unselected) {
return; // the reader cleared their choice
}
console.log(workflow.questionId, value);
});
value is helpful or unhelpful. A second click on the same button clears
the choice. The event then carries unselected: true and no value.
The SDK sends the feedback to Miso by itself. Listen to this event only to send it somewhere else as well, such as to Google Analytics 4.
The data event
data fires each time the data of the workflow changes. That includes a new
question, the request going out, and each part of the response as it streams
in.
client.ui.asks.on("data", ({ workflow, status, ongoing, value }) => {
if (status !== "ready" || ongoing) {
return;
}
console.log(workflow.questionId, value.sources);
});
The event carries the data object:
| Property | What it holds |
|---|---|
session | The session of the question. |
status | initial, loading, ready or erroneous. |
ongoing | true while more of the response is on the way. Set only when status is ready. |
request | The request that the SDK sent, with the body in request.payload. |
value | The Answer API response, with answer, sources and the other fields. |
error | The error, when status is erroneous. |
For one question, data fires in this order:
status: "initial"when the new question starts, with norequestyet.status: "loading"when the request goes out.status: "ready"andongoing: truefor each part of the response. This repeats as the answer streams in.status: "ready"andongoing: falsewhen the response is complete.
If the question fails, the last one has status: "erroneous" instead.
The event shows the data after each
data processor has run, so a field
you changed there arrives changed here. The event cannot change the data. To
change what Ask shows, use useDataProcessor.
data comes before the lifecycle events. The response is complete at
ongoing: false, but the answer can still be typing out on screen until
done.
If it does not work
| Symptom | Cause |
|---|---|
| Follow-up answers emit nothing | The listener is on client.ui.ask. Set it on client.ui.asks. |
workflow is undefined | The listener is on a single workflow. Events there do not carry workflow. |
value is undefined in data | The response has not arrived yet. Check status first. |
| A listener runs many times for one answer | It listens to data, which fires for each part of the response. Use done, or check ongoing. |
| Nothing fires and an error shows in the console | The function throws. The SDK logs the error and goes on. |
Next
- API Configuration — change the request and the response.
- Ask — Google Analytics 4 — send these events to GA4.
- Events & Custom JS — run your own code on the page.
