3
votes

I'm trying the amazing works done by https://github.com/FormidableLabs/urql/tree/master/packages/svelte-urql guys.

Everything works good until today issue.

I'm using the below code and it gives me this error:

Error: Function called outside component initialization
  at get_current_component (index.mjs:615)
  at getContext (index.mjs:648)
  at getClient (urql-svelte.mjs:55)
  at query (urql-svelte.mjs:81)
  at Players.svelte:41

Code:

<script>
  import { query } from '@urql/svelte'
  import { myQuery } from './myQuery'

  let players
  let myVars

  function sleep (ms) {
    return new Promise((resolve) => setTimeout(resolve, ms))
  }

  $: (async () => {
    await sleep(2000) // this gives me the error; removing it make it work
    players = query({
      query: myQuery,
      variables: { ...myVars },
      requestPolicy: 'cache-and-network'
    })
  })()
</script>

{#if !players}
  Loading players...
{:else}
  Players loaded! Do the work.
{/if}

Can you suggest what's the problem?

If I use await() in onMount() it works! Like this:

onMount(async () => {
  await sleep(2000)
  loaded = true
})

Here the code for @urql/svelte:

  1. query.ts: https://github.com/FormidableLabs/urql/blob/master/packages/svelte-urql/src/operations/query.ts
  2. context.ts: https://github.com/FormidableLabs/urql/blob/master/packages/svelte-urql/src/context.ts

Maybe the context code?

import { setContext, getContext } from 'svelte';
import { Client, ClientOptions } from '@urql/core';

const CLIENT = '$$_URQL';

export const getClient = (): Client => getContext(CLIENT);

export const setClient = (client: Client): void => {
  setContext(CLIENT, client);
};

export const initClient = (args: ClientOptions): Client => {
  const client = new Client(args);
  setClient(client);
  return client;
};

I can create a REPL on CodeSandbox if you need, no problem.

Bug on @urql/svelte: https://github.com/FormidableLabs/urql/issues/795.

Information about your Svelte project: - Chrome 83 - Svelte version: 3.23.0 - Rollup

2
Seems like these reactive statements don't like asynchronous functions. Do you need it for your logic? Why don't you use the await blocks from your other question: stackoverflow.com/questions/62087073/…Gh05d

2 Answers

2
votes

My situation was a bit different, but got the same error. In my case, I was trying to get Svelte/Sapper running in a Docker container for development purposes. I was fiddling around with the package.json before this and at some point I decided too move svelte and sapper to "depedencies" instead of "devDependencies".

"dependencies": {
    // ...
    "sapper": "^0.27.0",
    "svelte": "^3.0.0"
}

This was a bad idea. Once I moved it back to "devDependencies", the error went away and everything worked as expected.

"devDependencies": {
    // ...
    "sapper": "^0.27.0",
    "svelte": "^3.0.0"
}

I hope this helps someone down the line.

1
votes

If using Vite as a bundler, you will need to exclude @urql/svelte from dependency pre-bundling, which apparently caused this error for me.

Add this to your Vite config:

{
  optimizeDeps: {
    exclude: ['@urql/svelte']
  }
}

This also works for svelte-apollo, do the same but replace the package name!

Docs on Vite's dependency pre-bundling are there, if curious.