QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.84k stars 1.31k forks source link

[🐞] Use useNavigate in useTask$ generate an error #6714

Closed devcaeg closed 3 months ago

devcaeg commented 3 months ago

Which component is affected?

Qwik Runtime

Describe the bug

Use useNavigate in useTask$ generate an error:

useTask$(async ({ track }) => {
  track(() => store.step);

  navigate(`/publications/${location.params.id}/update/operation`);
});
Error: Code(3): Only primitive and object literals can be serialized

Reproduction

https://stackblitz.com/edit/qwik-starter-2jfbxe?file=src%2Froutes%2Findex.tsx

Steps to reproduce

No response

System Info

System:
    OS: macOS 15.0
    CPU: (8) arm64 Apple M2
    Memory: 267.70 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.4.1 - ~/.nvm/versions/node/v22.4.1/bin/node
    npm: 10.8.1 - ~/.nvm/versions/node/v22.4.1/bin/npm
    pnpm: 9.5.0 - /opt/homebrew/bin/pnpm
    bun: 1.1.20 - /opt/homebrew/bin/bun
  Browsers:
    Chrome: 126.0.6478.183
    Edge: 126.0.2592.113
    Safari: 18.0
  npmPackages:
    @builder.io/qwik: 1.7.1 => 1.7.1 
    @builder.io/qwik-city: 1.7.1 => 1.7.1 
    typescript: 5.5.3 => 5.5.3 
    undici: 6.19.2 => 6.19.2 
    vite: 5.3.4 => 5.3.4

Additional Information

No response

thejackshelton commented 3 months ago

Hey @devcaeg! This is because you're trying to navigate on the server, when the navigate function is used for programmatic SPA navigation based on an interaction.

import { component$, useSignal, useTask$ } from '@builder.io/qwik';
import { isServer } from '@builder.io/qwik/build';
import { useNavigate, type DocumentHead } from '@builder.io/qwik-city';

export default component$(() => {
  const navigate = useNavigate();
  const isClickedSig = useSignal<boolean>(false);

  useTask$(({ track }) => {
    track(() => isClickedSig.value);

    if (isServer) return;

    navigate('/demo/flower');
  });

  return <button onClick$={() => (isClickedSig.value = true)}>Hello</button>;
});

export const head: DocumentHead = {
  title: 'Welcome to Qwik',
  meta: [
    {
      name: 'description',
      content: 'Qwik site description',
    },
  ],
};

This works, because we make sure not to run the navigate function on the server.

devcaeg commented 3 months ago

@thejackshelton

You're right, that was the problem, big mistake of mine haha.