0

I have a parent component with two buttons. Button 1 should open iFrame with url 1 and button 2 url 2. It seems the way I built it the iFrame is not rebuilt entirely.

parent.js

if (currentTable.id === "Bo3Ko3K") {
    <DailyCo url="https://meeting.daily.co/123456" />
} else if (currentTable.id === "9RGmWxX") {
    <DailyCo url="https://meeting.daily.co/abcdef" />
}

child.js

import { makeStyles } from "@material-ui/core/styles";
import React, { useRef, useEffect } from "react";
import DailyIframe from "@daily-co/daily-js";

const useStyles = makeStyles((theme) => ({
  root: {
    width: "100%",
    height: "100vh",
    border: "0",
  },
}));

const DailyCo = ({ url }) => {
  const classes = useStyles();
  const iframeRef = useRef();

  useEffect(() => {
    if (!url) {
      console.error("please set an url!");
      return;
    }
    const daily = DailyIframe.wrap(iframeRef.current, {
      // showLeaveButton: true,
    });
    daily.join({ url });
  }, [url]);

  return (
    <iframe
      className={classes.root}
      title="video call iframe"
      ref={iframeRef}
      allow="camera; microphone; fullscreen"
    ></iframe>
  );
};

export default DailyCo;
4
  • 1
    Add a key to your DailyCo elements or to the iframe that differs based on the URL. Commented May 22, 2020 at 15:04
  • Hi Zachary, I already tried that, but it didn't resolve the issue despite different keys. Commented May 22, 2020 at 16:48
  • Could you elaborate further on the issue you are having? The keys will make sure that the component unmounts/remounts as shown here: codesandbox.io/s/elastic-microservice-i80p6?file=/src/App.js Commented May 22, 2020 at 19:42
  • Thanks a lot for the codesandbox! I used it to illustrate the problem: loom.com/share/9a2458c3ed394266808d85194df64733 You can see there with a fresh page load all runs perfect. However, as soon as I switch the roomID, the publisher video (left bottom) disappears. In the console it looks like that the other iFrames are just added in an overlay but not completely replaced. Here your version with ready to use tableIDs: codesandbox.io/s/sharp-wu-7gpgd?file=/src/App.js Expected behaviour is that the publisher in the left bottom always appears when switching the room. Commented May 22, 2020 at 20:10

1 Answer 1

1

You have 2 options I can see to get this working:

  1. You need to leave the meeting before joining a new one. Unfortunately this method is complicated by daily taking about 7ms (in an async manner) to leave a meeting. So, it isn't possible to just have the useEffect clean up normally. It's also fun because daily.leave() returns a promise that never resolves if you aren't in a meeting. Their documentation for leave() is currently misleading:

Leaves the meeting. If there is no meeting, this method does nothing.

Returns null;

https://codesandbox.io/s/reverent-grass-qpjke?file=/src/App.js

  const iframeRef = useRef();
  const dailyRef = useRef();
  const joinedRef = useRef();
  useEffect(() => {
    dailyRef.current = DailyIframe.wrap(iframeRef.current, {
      // showLeaveButton: true,
    });
    dailyRef.current.on('left-meeting',()=>{
      joinedRef.current=false;
    })
    dailyRef.current.on('joining-meeting',()=>{
      joinedRef.current=true
    })
    console.log("mounted");
    return () => {
      dailyRef.current.destroy();
      console.log("unmount");
    };
  }, []);
  useEffect(() => {
    (async () => {
      if (joinedRef.current) {
        // This is needed due to it never returning
        // if there wasn't a meeting joined first...
        await dailyRef.current.leave();
      }
      if (!url) {
        console.error("please set an url!");
        return;
      }
      await dailyRef.current.join({ url });
    })();
  }, [url]);

  1. You need to call daily.destroy() before creating a new Wrap, otherwise they interfere with each other and issues abound and the new one never fully sets up. This issue is described in their documentation for destroy

You can re-use the daily-js call iframe or call object multiple times (a sequence of join(), leave(), join(), etc method calls will work fine).

But when you are finished with the daily-js call object, you should call destroy() to free all resources associated with it.

This is particularly important if you plan to create another daily-js object in the future. If you don't call destroy(), and later create a new daily-js call object, the event listeners from the old object and the new object will interfere with one another.

https://codesandbox.io/s/spring-water-nv3k3?file=/src/App.js

  const iframeRef = useRef(null);
  useEffect(() => {
    if (!url) {
      console.error("please set an url!");
      return;
    }
    const daily = DailyIframe.wrap(iframeRef.current, {
      // showLeaveButton: true,
    });
    daily.join({ url });
    return () => {
      daily.destroy();
    };
  }, [url]);

In general, I'd recommend to use option 1 if only because it's more performant (less set up and time required to change meetings). Even though it's easier to just destroy the wrap and recreate it.

Sign up to request clarification or add additional context in comments.

7 Comments

Wow don't know what to say. That solved it all. Thank you so much! I will go with option 1.
Hi Zachary, I have one more follow up question. While adding a second button, I ran into another problem: loom.com/share/e9b03203fe42458f8b0abd44d250517b Once I click on "anotherComponent" while loading Daily, it turns into the error " Failed to execute 'removeChild' ". Do you have any idea how to fix that? I created the following Sandbox: codesandbox.io/s/blazing-darkness-5qp77?file=/src/App.js
Thank you for checking :) I actually solved it slightly different and used the event "joined-meeting" instead. That solved it as well: codesandbox.io/s/blazing-darkness-5qp77?file=/src/App.js
However, I am already facing the next problem. If I switch fast and in the right moment between ids, I get the error: "error: can't change the daily.co call url after load() ". loom.com/share/65ac66985b474518aabf60a94277df7a If you have any idea there, I would appreciate it.
I think adding joiningRef together with .leave() while switching solved it now: codesandbox.io/s/quirky-forest-qc8yj?file=/src/App.js:586-596
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.