qwik icon indicating copy to clipboard operation
qwik copied to clipboard

[🐞] If Signal is used by useTask$ it doesn't re-render should it work that way?

Open notcod opened this issue 1 year ago • 6 comments

Which component is affected?

Qwik Runtime

Describe the bug

On button clicking I set value of Signal to true, If Signal is true, I want to hide button until task is completed, it works with useVisualTask$ but doesn't work with useTask$, am I doing something wrong?

check out reproduction url https://stackblitz.com/edit/qwik-starter-sbzklc?file=src%2Froutes%2Findex.tsx,package.json

export const ServerTask = component$(() => {
  const page = useSignal(1);
  const loading = useSignal(false);
  useTask$(async ({ track }) => {
    track(page);
    if (loading.value) {
      await new Promise((r) => setTimeout(r, 1000));
      loading.value = false;
    }
  });
  const increase = $(async () => {
    page.value++;
    loading.value = true;
  });
  return (
    <>
      {page.value} - {loading.value ? 'loading...' : 'loaded!'}
      <br />
      {!loading.value && <input type="submit" onClick$={increase} />}
    </>
  );
});

Reproduction

https://stackblitz.com/edit/qwik-starter-sbzklc?file=src%2Froutes%2Findex.tsx,package.json

Steps to reproduce

No response

System Info

npx envinfo --system --npmPackages '{vite,undici,@builder.io/*}' --binaries --browsers

Additional Information

No response

notcod avatar Feb 19 '24 11:02 notcod

Looks like there's an issue with the useVisibleTask example too. The page count doesn't increase past 2.

tuurbo avatar Feb 19 '24 17:02 tuurbo

Looks like there's an issue with the useVisibleTask example too. The page count doesn't increase past 2.

I didn't saw it at first, but you are right, maybe that's also a bug? I have edited the code

    {!loading.value && (
      <input
        type="submit"
        value="Button that works only one time with useVisibleTask$, but always with useTask$, why?"
        onClick$={increase}
      />
    )}
    <input
      type="submit"
      onClick$={increase}
      style={`${loading.value && 'background:red;'}`}
    />

notcod avatar Feb 20 '24 07:02 notcod

I wanted to take another look and try a few things. It seems the use of await inside useTask is causing the bug. I created an example repo with 3 example components. The only difference between each component is the code within the useTask. https://stackblitz.com/github/tuurbo/qwik-task-bug?file=src%2Froutes%2Findex.tsx

tuurbo avatar Feb 21 '24 19:02 tuurbo

I think I encounter a similar bug in the QwikCityProvider in line 504. The update call routeLocation.isNavigating = false; is triggered, but useTask$ is not always notified. It works with useVisibleTask$ for me.

fabian-hiller avatar Feb 25 '24 18:02 fabian-hiller

Let's wait until v2 alpha is out to check if the bug still exists there. In the mean time it would be very helpful to create the repro in https://qwik.dev/playground so that it's easy to test with the alpha

wmertens avatar Feb 27 '24 16:02 wmertens

Here is a slimmed down example

https://qwik.dev/playground/#f=7ZdNb9NAEIb%2Fymg5JLSJkyJFRUkDEtATEpUoiCNyHCexcGzLdmhQlP%2FOO7OzaycupVckfGjj9e7szOx8PNsOmtfXk8eiZuB7rvySujagJ4PJS0mqd2X%2BwA1PZ5vOscq7eWYAKjEIUcy9XtaL%2FJ0fxocpXQ30NUWe4zSntArTKrajR%2FvPrUAmIUJ%2BYhVXa51iXeT3TDJOOBTaObUVIqtMwJteXs4wwpnQaBrXXGeYfGSdV2aRg0zCrCNHJ2C2%2FuqIRBV9H6LWszxbV9vaaFy1GmC%2FX8r3pnn3ywFdjcfjlxDrhXsSUpkHpZtjS7iMqPGN2XY9UbKivj9vm1f8jC7koQ93t%2FefvtC3u88fyQ5djHSKbdpqWF%2B0Eo945%2FXl7NxGRGeiWeb9uVBghpcYcNM9OTX5%2FugW%2Fis7xkWCOukPWQsyVm40Rbi0Bzwp9jP6vkJ5Hj7EyXpT85mnyxnJUIUegRi9xiTTpOztvhComgI6uIda0iagExjjxhLxmy2SI0ErvhnpgHBFRXVuY1T4RRDaAlhALgIrMCAgJtqEGb7a5M3yHq%2Fs%2FYqrHi13wuir8AewCc06gvMCX0CY%2F%2F9q8Ra4lWTDRQ7Nt7BwzINPmPy14h17EgE9GFChuflYxPEwqkC%2FBRgKfBDt0qJM6oCU00Yo7UpsUY6FzGGgE78eKyGCMV78CjEb9O%2B8fL5Rr8QAcHMB2EENSWO2B3%2BHy6S0wIYrUJ7uttmM1mHhTAYFrLOhoJZdNcTNp6xnCIIS1Q%2BCiz0B7JIlvYiiyDlOl7ccJNcvW9IOTc4dTzTXWb646ERXS96SwfEampLJctNZaqPMvyPN0ZTnxg6b1ri7PcxP5XN%2BuMffhQ6nydZJaC60Ptns4ypsUwAk%2B9ri9XJ2KjXalVUOjxoB47g0rvKrSkUYJTXO7twp42ACl%2Fg%2BIZuBVPla1OzZ%2BIk0HRvHuZtwN5iaDvsfi%2F5JLPoN

tuurbo avatar Feb 27 '24 18:02 tuurbo

this works as expected because of how promises work

here is the correct way to handle true/false loading

          onClick$={[
            $(async () => {
              await setLoading(true);
            }),
            $(async () => {
              await increase();
              await apiCall();
            }),
            $(async () => {
              await setLoading(false);
            })
          ]}

(the added benefit is that if the page changes the rest of the handlers don't get invoked)

https://qwik.dev/playground/#f=7VhRb9NADP4rVnhIxtq0G5rQ2hUkYE9ITGIgHhBCaZpuEW0SJS0bmvrf%2BWxf7i5LNybxhEQe1sR39tk%2B33ef5xXN8YvT031VM7B3rrwJrg3IiBW6HqkrazBv3tTlDd99ZnbQ22H5Dp5Yi5pY4Qoz50p0dGDHlHjoIL9qslmXH9ac0NHAfK4AB9j0CS2TVZOpdKc%2FrQYOHArpJ7QY1M0UzaRdMy%2F4XAKPZ%2BQ7S%2BpMzIseHk5Fwu8xUGRrJT5hCXk4HHh6A0%2BDg%2BQj52LNNgxoTLFkZRvOvITFpOh5YiZgtnljFzomAddvE1wqbE8B3I%2Bnd9FGUS3DjiRE9YCOxuPxAaxa27j9LekyVu8MkdpZ85hEKvRyKMJ7SZI5nSxxZsxMc8bcWDvkXCHKlxTZ0lQ0MOqj5%2FLQu4vzyw%2Bf6MvFx%2FekouejB9yZZ2BPoBxVHnp%2BaKpMOiNJxj7lZAmutl%2FX7W4k5fmgjQWOCdRNwfZj4SAu90SBH%2BtfzAyln3f5ecwR%2FHBi2xzri0n1A3CHlsIQ7qBKFlqwJ9XtlL4vca8Nb7L86nrDNbxaTElEDS5XnNqXmBQ4rDu%2FrYSNTsDWmHxoi0LgnCBnZ9pKvFoDSnJwmLOREQgha2hT6qkV4id4osw1pvZENSDPYH%2FpdVJgVKGuKEPWDH9lTUiLrTQ3y%2BSHbD6lSGRskZcbpz9GvAZPzYvhvITna0Q4ZuEjIX9ueMVQ6iNEAA1YgT1Z2CfmePBvDvIJYpVuV1Wdb2IyBHeEO9FQ3bSEIhNY0DqrD02Y4P5H8goz1yA%2BZf30oI4lADQcFVgiUHWVcTz4O1zktTJd9I7larsupnSVVG3IoE9XxVA4qmoN0TLWmymKoMZdAcPVLaHg8wU9S9O0TZxR9xIkfauC%2FJ2DgF3HczPLgqWZ2GLjawqwvQFNKCjKoKeqVWa%2FgVhgM7NAxYEnb9uuWdc%2BH5H2sU3k3VdPSnuh1z09dOCLSc6ge3YH7RX3dIvtLaZg1R%2FvYNnfLbUXUXyT3uc3P2OmUe9aTbd1U6JIAmmSsjroOlRWSZpvUI7393kcn2CXLRmQldG1cIvs1nRbTwZhXC20%2FxXpnw%2FHtv5T5H%2BSIv8G

the reason why the example before only worked with .then() is that it was a side-effect

apiCall().then(() => {
  setLoading(false);
});

the signal was fired async after apiCall finishes the task

PatrickJS avatar May 06 '24 04:05 PatrickJS