Provide asynchronous search results
In Workspace 8.0 and later versions, you can implement APIs and methods that support better performance and efficiency in returning the results of large or complex searches.
For the basics of implementing search providers, see the explanations and examples in Home overview.
How it works
To support asynchronous search results, only the list of results that match the search request is returned initially. This is supported by the dispatchFocusEvents
property of the HomeProvider
API. When the user requests additional information about a selected result, the UserAction
and FocusChange
values of the new ActionTrigger
enum dispatch events to the HomeProvider to request the result details. This approach means that the Provider does not have to send all the details of all search results at once, but instead can send them as needed.
Examples
Set the dispatchFocusEvents
property of the HomeProvider
API to true
in your onUserInput
function:
const signal = makeHomeResultSignal();
const fullResults = {};
let response;
async function onUserInput (
req: HomeSearchListenerRequest
res: HomeSearchListenerResponse
) {
const shallowResults = getShallowResultsFor(req.query);
// Open the listener response for push updates
response = res;
response.open();
signal.set(async (result: DispatchedSearchResult) => {
if (!fullResults[result.key]) {
// Fetch the full result for this search result.
fullResults[result.key] = await getFullResultFor(result.key);
// Update the result with the full template.
response.respond([fullResult]);
}
});
return shallowResults;
}
async function onResultDispatch(result: HomeDispatchedSearchResult) {
switch (result.action.trigger) {
//...
case ActionTrigger.FocusChange:
// The user has focused on this search result.
await signal.notify(result);
break;
}
}
await Home.register({
//...
onUserInput,
onResultDispatch,
dispatchFocusEvents: true
});
To return results when the user selects them, and to support updating selected results in realtime, a fuller version of the onResultDispatch
function with the ActionTrigger
enum looks like:
async function onResultDispatch(result: HomeDispatchedSearchResult) {
switch (result.action.trigger) {
case ActionTrigger.UserAction:
handleUserAction(result.action.name);
break;
case ActionTrigger.FocusChange:
case ActionTrigger.Reload:
updateResult(result.key, useLoadingTemplate());
try {
const fullData = await fetchDataFor(result.key);
updateResult(result.key, makeTemplate(fullData));
} catch(e) {
updateResult(result.key, useErrorTemplate());
}
break;
}
}
Include templates to indicate result loading state
To support good user experience for these asynchronous responses, we also provide a LoadingTemplate
API to indicate that results are loading, and an ErrorTemplate
API to allow the user to retry a failed request for search result details.
For examples of how to work with async search results and these templates, see the workspace-starter example.
Updated about 2 years ago