#Function hoisting within components

2 messages · Page 1 of 1 (latest)

polar panther
#

Hey everybody, I'm new with Qwik and I was trying to implement a simple timer. However I ran into a problem, which I do not know how to solve with Qwik.

I have 3 functions: runTimer, pauseTimer and decrement.

runTimer invokes decrement with a setInterval.
pauseTimer clears the interval.
decrement decrements the timer and when the timer is 0, it will do stuff and invoke runTimer again.

So runTimer should be able to invoke decrement and vice versa. However as they are not defined via the function foo() {} annotation but the const foo = $(() => {}); annotation. Hence the order of declaration matters. But since they can both invoke each other, it will always be a problem.

Is there any other way in Qwik to solve this problem? I will try to post a stripped example, but it seems to be too long for Discord.

#

Here's the example

import { component$, useSignal, $ } from "@builder.io/qwik";

export const ExampleTimer = component$(() => {
    const windowInterval = useSignal<number | undefined>();

    const pauseTimer = $(() => {
        clearInterval(windowInterval.value);
    });

    const decrement = $(async () => {
        /* Some logic here to decrement the timer */
        console.log('2) Decreasing timer from 1sec to 0sec');

        /* If end of the timer is reached, pause timer, do some stuff and resume timer again */
        if ('end reached' === 'end reached') {
            /* Pause timer */
            console.log('3) End reached, stopping timer');
            pauseTimer();

            /* Some async logic here, resetting timer */
            console.log('4) Resetting timer and doing async stuff');

            /* Start timer again */
            runTimer(); /* 🐞 Here's where the problem occurs, since runTimer() is defined later */
            console.log('5) Re-started timer');
        }
    });

    const runTimer = $(() => {
        windowInterval.value = setInterval(decrement, 1000);
    });

  return <button onClick$={() => {
        console.log('1) Starting timer');
        runTimer();
    }}>Run</button>;
});