Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to get event handlers working #156

Closed
Jack-Barry opened this issue Apr 19, 2023 · 7 comments
Closed

Unable to get event handlers working #156

Jack-Barry opened this issue Apr 19, 2023 · 7 comments

Comments

@Jack-Barry
Copy link

When setting up dashboards or looks with an SSO embed URL using LookerEmbedSDK.createLookWithUrl or LookerEmbedSDK.createDashboardWithUrl, none of the event handlers seem to do anything in our app. The embed loads just fine and renders a report, but nothing gets logged to console, even with something where all of the documented event types are handled:

const logEventForDebugging = (event) => { console.log(event) }

LookerEmbedSDK.createDashboardWithUrl(url)
  .appendTo("report")
  .withClassName("looker-embed")
  .withNext()
  .withFilters({})
  .on("dashboard:run:start", logEventForDebugging)
  .on("dashboard:run:complete", logEventForDebugging)
  .on("dashboard:filters:changed", logEventForDebugging)
  .on("dashboard:edit:start", logEventForDebugging)
  .on("dashboard:edit:cancel", logEventForDebugging)
  .on("dashboard:save:complete", logEventForDebugging)
  .on("dashboard:delete:complete", logEventForDebugging)
  .on("dashboard:tile:start", logEventForDebugging)
  .on("dashboard:tile:complete", logEventForDebugging)
  .on("dashboard:tile:download", logEventForDebugging)
  .on("dashboard:tile:explore", logEventForDebugging)
  .on("dashboard:tile:view", logEventForDebugging)
  .on("drillmenu:click", logEventForDebugging)
  .on("drillmodal:explore", logEventForDebugging)
  .on("explore:run:start", logEventForDebugging)
  .on("explore:run:complete", logEventForDebugging)
  .on("explore:ready", logEventForDebugging)
  .on("explore:state:changed", logEventForDebugging)
  .on("look:run:start", logEventForDebugging)
  .on("look:run:complete", logEventForDebugging)
  .on("look:save:complete", logEventForDebugging)
  .on("look:delete:complete", logEventForDebugging)
  .on("look:ready", logEventForDebugging)
  .on("look:state:changed", logEventForDebugging)
  .on("page:changed", logEventForDebugging)
  .on("page:properties:changed", logEventForDebugging)
  .on("session:token:request", logEventForDebugging)
  .on("session:status", logEventForDebugging)
  .on("env:client:dialog", logEventForDebugging)
  .build()
  .connect()
  .then((embed) => {
    // do stuff with embed
  })
  .catch((error) => {
    // handle error
  });

Is there anything we could be doing wrong/missing that prevents those event handlers from being invoked?

@williamtsoi1
Copy link

williamtsoi1 commented Apr 21, 2023

+1 on this, I've been battling this for the last week too!

Here's my bit of code, looks fairly similar to yours:

LookerEmbedSDK.createDashboardWithId(1)
      .appendTo(document.getElementById("dashboard"))
      .withClassName("embeddedDashboard")
      .on("dashboard:loaded", (e) => {
        console.log(
          "LookerEmbedSDK.createDashboardWithId()::Successfully Loaded!"
        );
      })
      .on("page:properties:changed", (e) => {
        pagePropertiesChangedHandler(e, el);
      })
      .on("dashboard:run:start", (e) => {
        console.log("Dashboard started");
      })
      .on("dashboard:run:complete", (e) => {
        console.log("Dashboard complete");
      })
      .build()
      .connect()
      .then((dashboard) => {
        setDashboardEmbedded(true);
        console.log("LookerEmbedSDK.createDashboardWithId()::Connected!");
      })
      .catch((error) => {
        console.error("An unexpected error occurred", error);
      });

@williamtsoi1
Copy link

williamtsoi1 commented Apr 21, 2023

I actually resolved this by looking at this comment from another issue.

I needed to add a .withApiHost( ... ) and then it started working for me. I can't find this anywhere in the SDK docs which was a bit frustrating to be honest

@Jack-Barry
Copy link
Author

I saw the .withApiHost() comment before opening this issue, and gave it a shot, but no luck. I wonder if it's a difference between createDashboardWithId vs. createDashboardWithUrl (creating with ID vs. URL)

@jarrettch
Copy link

jarrettch commented Apr 28, 2023

I believe I'm running into a similar issue. I'm trying to resize the iFrame dynamically so that our Looker dashboard doesn't have a y scrollbar. I'm using .createDashboardWithUrl and attempting to use the .withDynamicIFrameHeight helper. I also tried using version 1.8.2 but this snippet from the docs didn't work:

  const pagePropertiesChangedHandler = ({height}, id) => {
    if (height && height > 100) {
      const el = document.querySelector(`#${id} iframe`)
      if (el) {
        el.style.height = `${height}px`;
      }
    }
  };

    LookerEmbedSDK.createDashboardWithUrl(url)
      .on('page:properties:changed', (event) => {
        pagePropertiesChangedHandler(event, 'dashboard')
      })
      .appendTo('#dashboard')
      .build()
      .connect()

I haven't found a workaround yet. Curious if you got things working @Jack-Barry ?

@Jack-Barry
Copy link
Author

@jarrettch I haven't found anything yet, but still need to double-verify some things in our Looker configuration. There's quite a few moving parts for us, so I need to make sure this isn't just an issue because it's running on localhost vs. one of our other allowed domains

Also, I don't know yet if creating by ID absolutely has to be done first before calling create by URL, if that is maybe related to this issue. We generate the signed URL entirely via a backend service for all reports, so creating by ID on the frontend (AFAIK) is not viable for us. The docs say something here, so I donno if there's some magic done when creating by ID that is required for the event handlers to work properly

@williamtsoi1
Copy link

A few things to check:

  1. Have you set the Embedded Domain Allowlist in your Looker instance? This is often overlooked for development environments such as https://localhost:3000. Note that the protocol http/https as well as port number needs to be exact.
  2. Have you ran LookerEmbedSDK.init('looker.example.com', '/auth'), ensuring that the domain of your Looker instance is set correctly? In my situation I found out that I was supposed to be loading it from an environment variable but it wasn't working properly and so the domain passed into the init() function was undefined.
  3. Assuming that the iframe renders correctly, then the /auth reference should not be a problem, else you would not be able to get the embedded URL.
  4. If you're using React, ensure that LookerEmbedSDK.createDashboardWithUrl() is run from inside a useEffect() hook (docs here). Here is a full React component that works and all the events are fired into the browser console:
import React, { useCallback, useEffect, useRef } from "react";
import styled from "styled-components";
import { LookerEmbedSDK } from "@looker/embed-sdk";

const LookerEmbedDashboard = () => {
  const [dashboardEmbedded, setDashboardEmbedded] = React.useState(false);
  const dashboardRef = useRef(false);
  useEffect(() => {
    if (dashboardRef.current) return;
    dashboardRef.current = true;
    makeDashboard();
  }, []);

  let makeDashboard = async () => {
    // LookerEmbedSDK.init(...) is already run at the page level
    LookerEmbedSDK.createDashboardWithId(1)
      .withDynamicIFrameHeight()
      .appendTo(document.getElementById("dashboard"))
      .withClassName("embeddedDashboard")
      .on("dashboard:loaded", (e) => {
        console.log(
          "LookerEmbedSDK.createDashboardWithId()::Successfully Loaded!"
        );
      })
      .on("dashboard:run:start", (e) => {
        console.log("Dashboard started");
        console.log(e.dashboard.dashboard_filters);
      })
      .on("dashboard:run:complete", (e) => {
        console.log("Dashboard complete");
      })
      .build()
      .connect()
      .then((dashboard) => {
        setDashboardEmbedded(true);
        console.log("LookerEmbedSDK.createDashboardWithId()::Connected!");
      })
      .catch((error) => {
        console.error("An unexpected error occurred", error);
      });
  };

  return (
    <>
      <Dashboard id="dashboard"></Dashboard>
    </>
  );
};

// A little bit of style here for heights and widths.
const Dashboard = styled.div`
  width: 100%;
  height: 100vh;
  min-height: 100vh;
  > iframe {
    width: 100%;
    height: 100%;
  }
`;

export default LookerEmbedDashboard;

@Jack-Barry
Copy link
Author

Thanks @williamtsoi1, turns out step 1 was the missing part for us

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants