5

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

Fred Hors
  • 3,258
  • 3
  • 25
  • 71
  • 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: https://stackoverflow.com/questions/62087073/svelte-3-async-onmount-or-a-valid-alternative – Gh05d May 30 '20 at 15:07

2 Answers2

2

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.

Teodor Maxim
  • 471
  • 6
  • 9
1

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 to move svelte and sapper to "dependencies" 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.

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80
Phil
  • 3,342
  • 5
  • 28
  • 50
  • 1
    I would have _never_ guessed this could have been the issue but it sure was for me. Thanks! I think what's happening is that, since svelte's whole thing is not shipping framework code to the client, all its stuff needs to be in devDependencies. In my case, it was svelte-apollo that was in the wrong place. – sunny-mittal Nov 29 '20 at 17:41