1

I would like to terminate a Twilio call. The issue however is that, when I resolve the promise to connect the call and update a state with the call object and try to access this state outside the promise (inside a 'Terminate Call' button), I get undefined, as though the state has not been updated.

My console.log seems to indicate that the state has not been updated as assumed.

Here is my code:

    //this is a global variable
    let checkCall = false

    const [call, setCall] = useState();
    ...
    useEffect(() => {
        function selectDriver() {
            driverInState.current = sortUsersAlphabetically([user.username, matchedUserState.current])[0]
        }
        console.log('!!!*** how many times is twilio being called ***!!!')
        WebSocketInstance.connect()
        selectDriver()
        const params = {
            roomName: roomName, participantLabel: user.username
        };
        if(checkCall === false){
            if (!call) {
                const callPromise = device.connect({ params });
                callPromise.then((twilioCall) => {
                console.log(' ***what is call', twilioCall)
                setCall((prev) => twilioCall);
                setCallConnected(true)
                });
            }
            if (!participants.current.includes(user.username)) {
                    participants.current.push(user.username);
            }
            checkCall = true
        }
    }, [roomName, user, call, device, participants, driverInState,matchedUserState,sortUsersAlphabetically]);
    
    const handleLeaveRoom = () => {
      console.log("INSIDE FUNCTION TO TERMINATE CALL", JSON.stringify(call));
      call.disconnect();
    };
    const endCall = () => {
      handleLeaveRoom();
      setState({ ...state, createdRoomTopic: null });
    };
    ...
    return (
        <>
            <button onClick={ ()=> endCall() }>End Call</button>
            ...
        </>
        )

Inside the useEffect, I can console log the call object in state. However, in the handleLeaveRoom function, I cannot console log the call object

Emm
  • 2,367
  • 3
  • 24
  • 50
  • 2
    the `call` in `if (!call) {` is not the same variable as `call` in `.then((call) => {` ... I would not recommend using identical variable names like this as it leads to confusion, obviously. So where is the first `call` declared and is that the one you're trying to use in `handleLeaveRoom`? – Jaromanda X Nov 16 '22 at 01:33
  • Where (and *when*) are you calling `handleLeaveRoom`? – Bergi Nov 16 '22 at 01:56
  • @JaromandaX I added that to my code. Call is a state. `handleLeaveRoom` is triggered by a button. This button is only visible when the call is connected (I removed this logic so I could better understand where the problem was). @Bergi I am only clicking `handleLeaveRoom` after the call connects (Twilio plays a tone when the call connects) – Emm Nov 16 '22 at 02:59
  • Why the `setTimeout`? You're not passing a function btw – Bergi Nov 16 '22 at 03:04
  • @Bergi I don't need that, just wanted to console.log what was in state for debugging purposes. I assumed I could use a setTimeout to console log what's in state because useState is asynchronous and I might not see what's in state immediately - not sure if this logic makes sense? – Emm Nov 16 '22 at 03:05
  • 1
    [No, it doesn't](https://stackoverflow.com/q/54069253/1048572) (the `call` state is a `const`ant you close over), and as Jaromanda said, you're logging the variable from the promise callback anyway, not the state. Just put a `console.log(call)` right inside your render function, or `useEffect(() => { console.log(call); }, [call]);` if you feel fancy, to log the actual state. – Bergi Nov 16 '22 at 03:07
  • @Bergi so when I try that ie. `useEffect(() => { console.log(call) }, [call])` I get undefined even though the call is starting (and presumably the call object is added to state in my promise – Emm Nov 16 '22 at 03:13
  • There's a lot of things that don't make sense about the code as-is - I know you've tried to simplify it to the part where you think the problem is, but we don't know the rest of the context so we may not be able to help. For example, what is `checkCall`? Why are there no dependencies listed for your `useEffect`, even though your effect clearly has dependencies (`roomName`, `user`, `checkCall`...)? What does each log statement show? – gerrod Nov 16 '22 at 03:38
  • @gerrod I have re-edited my code. I added all the dependencies required to the dependency array. `checkCall` is a global variable just to check if the call has already been initiated. `What is call` returns the call object (includes a disconnect method) The console.log inside `handleLeaveRoom` returns undefined – Emm Nov 16 '22 at 03:55
  • 1
    Using `setCall` within an effect hook with `call` as a dependency is a sure-fire way to run an infinite render loop – Phil Nov 16 '22 at 03:58
  • @Phil just to clarify, are you suggesting removing call from my dependency array? That doesn't seem to make ESLint happy – Emm Nov 16 '22 at 04:00

0 Answers0