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.