Events and app integration

Events and app integration

ThoughtSpot supports a range of events that your app can listen to and respond to with appropriate actions. The embedded ThoughtSpot components emit events when they initialize and load, and when a user executes an action inside these components. The host application can also trigger events within the embedded ThoughtSpot objects, causing an alert or other action.

The SDK library includes the following event objects:

  • EmbedEvent

  • HostEvent

Embed eventsπŸ”—

Embed events are emitted by the embedded ThoughtSpot components and are part of the EmbedEvent object. Embed events are emitted when ThoughtSpot components initialize and load, or when users interact with these components. For example, you can register an event handler to trigger EmbedEvent.Save when a user clicks the Save action on the Answer page in the embedded UI. You can also define a listener for an EmbedEvent with a callback function to handle the event response via the .on(embedEvent, eventHandlerCallbackFunction) format. For some of these action-triggered events, you can register event handlers to emit events when the corresponding action starts and ends.

For more information, see EmbedEvent.

Host eventsπŸ”—

Host events are triggered by the host application in which ThoughtSpot components are embedded. Host events use the .trigger() method to send the event message to embedded ThoughtSpot components in the .trigger(hostEvent, data) format. The host events are part of the HostEvent object; for example, HostEvent.SetVisibleVizs.

To explore the host event functionality in the Playground, follow these steps:

  • Go to Develop > Visual Embed SDK > Playground.

  • Select the feature to embed, for example, Search.

  • Select the objects to load in the Playground.

  • In the event handler code, add a host event as shown in the following example:

    document.getElementById('tryBtn').addEventListener('click', e => {
      embed.trigger((HostEvent.DownloadAsPng)
    });
  • Click Run.

  • Click Try Event to trigger the action.

The following video shows how to register HostEvent.RemoveColumn and remove a column from the search query string using the Try button:

For more information, see HostEvent.

Import Events libraryπŸ”—

Import the event library from the Visual Embed SDK package.

import { EmbedEvent, HostEvent } from '@thoughtspot/visual-embed-sdk';

To trigger events on ThoughtSpot components embedded in a React app, import the useEmbedRef hook.

import { LiveboardEmbed, useEmbedRef } from '@thoughtspot/visual-embed-sdk/react';
Try it out in Playground

Handle load and errors for embedded componentsπŸ”—

A common workflow is to use an overlay div element to hide the embed content until you know that SSO has completed, and the content is fully loaded. If an error occurs in the process, you may prefer to display your own custom message to the end user rather than showing embedded ThoughtSpot content in an error state.

Embed events fire at points within the loading process. The following events are related to the load process:

  1. Init
    Fires at the beginning of the loading process.

  2. NoCookieAccess
    Some browsers (Safari in particular) default to strict settings on cookie origins that prohibit the standard SSO process. This event fires if cookies are restricted by a user’s browser.

  3. AuthExpire
    Fires if SSO does not complete and if the ThoughtSpot session times out at some point. Listen to the AuthExpire event in the load process to determine when it is safe to show the ThoughtSpot content, and listen to it after loading to hide the ThoughtSpot login screen if the session expires for some reason.

  4. AuthInit
    Fires when the SSO process is completed correctly. The event does not fire when an SSO process fails, instead AuthExpire fires in that situation. The logged-in user GUID is available in the AuthInit event response.

  5. Error
    Fires when an error occurs in the embedded app. For information about error types, see Error types.

  6. Load
    Fires as soon as the area for embedding is created, not when the content has begun or finished loading.

  7. Data
    Fires only on SearchEmbed components. Does not fire on a LiveboardEmbed component.

  8. LiveboardRendered
    Fires only on LiveboardEmbed components when the Liveboard or visualization container loads.

AuthExpire and AuthInit can be used together to determine if the SSO process is completed correctly. To determine if AuthExpire is firing because SSO did not complete or if the ThoughtSpot session has timed out, you can set a variable to act as a flag to determine if SSO is completed. When AuthInit fires, set the flag to true. You can also associate a callback function to AuthExpire to look up the flag to determine which state change has caused the AuthExpire event to fire. In the following example, the tsLoggedIn flag is set to indicate the SSO login state.

// Instantiate class for embedding a Liveboard
const embed = new LiveboardEmbed("#thoughtspot-embed", {
    liveboardId: '<Liveboard-guid>',
});
let tsLoggedIn = false;
embed
    .on(EmbedEvent.Init, showLoader)
    .on(EmbedEvent.NoCookieAccess, showCookieSettingsMsg)
    .on(EmbedEvent.AuthInit, (response) => {
        // Set that AuthInit has fired
        tsLoggedIn = true;
        // authInit returns object -> {type: 'authInit', data: {userGuid: <guid>} } }
        let userGUID = response.data.userGuid;
    })
    .on(EmbedEvent.AuthExpire, (response) => {
        // Handle if session dies while content shows
        if (tsLoggedIn == true) {
            tsSessionTimeoutCleanup();
        } else {
            // Display custom message if SSO issues
            showSSOFailedMsg();
        }
    })
    .on(EmbedEvent.Error, showGenericErrorMsg)
    .on(EmbedEvent.LiveboardRendered, hideLoader)
    .render()

Error typesπŸ”—

The EmbedEvent.Error is fired when the following types of errors occur.

  • API
    API call failure error. This error event occurs when an API request is blocked.

    SearchEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "API", error: { message: '...', error: '...' } } }
    });
  • FULLSCREEN
    Error in presenting a Liveboard or visualization in full screen mode.

    LiveboardEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "FULLSCREEN", error: {
        //   message: "Fullscreen API is not enabled",
        // } }}
    })
  • SINGLE_VALUE_FILTER
    Error in updating filter values. This error occurs when a single value filter is applied on a Liveboard and the user tries to update this filter with multiple values.

    LiveboardEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "SINGLE_VALUE_FILTER", error: {
        //  message: "Filter {filter_name}: Cannot pass multiple filtering elements to this single value filter.",
        // } }}
    })
  • NON_EXIST_FILTER
    Error in applying filter due to a non-existent filter.

    LiveboardEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "NON_EXIST_FILTER", error: {
        //  message: "UpdateFilters could not update the filter on {filter_name} as it is not an existing filter in the Liveboard. Please edit the Liveboard and add {filter_name} as a filter chip in order to update it programmatically.",
        // } }}
    })
  • INVALID_DATE_VALUE
    Error due to invalid date value in a filter. For example, if the column name is Commit Date and a correct date value is not specified, the INVALID_DATE_VALUE error event is fired.

    LiveboardEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "INVALID_DATE_VALUE", error: {
        //  message: "UpdateFilters could not update the filter on {filter_name} as invalid date value provided.",
        // } }}
    })
  • INVALID_OPERATOR
    Error due to the use of invalid operator during filter application. For example, if you are filtering a column called Revenue and set the operator as In instead of EQ and specify multiple values, the filter application may fail.

    LiveboardEmbed.on(EmbedEvent.Error, (error) => {
        console.log(error);
        // { type: "Error", data: { errorType: "INVALID_OPERATOR", error: {
        //  message: "UpdateFilters could not update the filter on {filter_name} as invalid operator value provided.",
        // } }}
    })

SearchEmbed EventsπŸ”—

There are several events that fire only on the SearchEmbed component:

  • DataSourceSelected

    Fires when a change occurs in the data sources, including the initial load of the SearchEmbed component. Can be used to hide a loader screen. Return object contains an array of the selected column GUIDs (accessible using LOGICAL_COLUMN type within metadata REST API commands).

  • QueryChanged

    Fires when a change occurs in the search bar, including the initial load of the SearchEmbed component. The returned object includes a data.search property with the TML search query from the search box.

Handle custom action eventsπŸ”—

If you have added a custom action set as a callback action, you must register an event handler to send data in a payload when the custom action is triggered:

searchEmbed.on(EmbedEvent.customAction, payload => {
    const data = payload.data;
    if (data.id === 'show-data') {
        console.log('Custom Action event:', data.embedAnswerData);
    }
})
liveboardEmbed.on(EmbedEvent.CustomAction, (payload) => {
     if (payload.data.id === 'show-data') {
      const showActionId = 'show-data';
          if (payload.id === showActionId \|\| payload.data.id === showActionId) {
               showData(payload);
          }
      })

Filters in embedded UIπŸ”—

Runtime filters can be set programmatically before loading the embedded ThoughtSpot content in the options object set in the LiveboardEmbed component constructor.

Runtime filters can be updated after load time by triggering the HostEvent.UpdateRuntimeFilters event. You can build the filter UI in the embedding app, which triggers the UpdateRuntimeFilters event when changed or with the click of an apply button.

Filtering from selectionπŸ”—

Filtering from a selection on a chart or table can be implemented by combining the EmbedEvent.VizPointClick or EmbedEvent.VizPointDoubleClick events with the HostEvent.UpdateRuntimeFilters event.

The callback function from the VizPointClick event will need to read the response, parse out the attributes from the response that will be sent to the Runtime Filters, and then send the attributes and their target fields in the format used by UpdateRuntimeFilters.

ThoughtSpot filters overviewπŸ”—

ThoughtSpot Liveboards have four levels of filters.

Row-level security (RLS) rules

Tied to the logged-in user and their group memberships. Completely secure and cannot be altered by the logged-in user.

Runtime filters

Set via the Visual Embed SDK or URL parameters. Runtime filters do not display as UI filter components.

Answer filters

Established via the search definition, not visible as UI filter components on a Liveboard, but can be viewed in Explore or Edit modes.

Liveboard filters

Visible as UI components at the top of a Liveboard, affecting all visualizations on the Liveboard.

Modify SearchEmbed behaviorπŸ”—

The hideResults parameter in the options object of a SearchEmbed constructor blocks the GO button from displaying the chart or table results. When this option is true, you can listen to the QueryChanged event to perform actions based on the user’s interaction within the SearchEmbed component.