-
-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need full example svelte-apollo with sapper #9
Comments
I think i also need this it's not completely clear from the sapper example. Be great to see the setup using the stock sapper template! |
I had been waiting for the various sapper updates to land for svelte v3 before looking into this, but it looks like I missed the memo and it's been released with v0.26 of sapper. I'll take another look at this soon. |
Would like to see this as well! |
Apologies for being "that person", but are there any updates on this topic or guidance in the meantime? I have been unable to find a good way of configuring this with Sapper UPDATE: I got this working by using
<script>
import ApolloClient from "apollo-boost";
import { setClient } from "svelte-apollo";
const client = new ApolloClient({
uri: "https://..."
});
setClient(client);
</script>
...
<script>
import { getClient, query } from 'svelte-apollo';
import { GET_BOOKS } from './queries';
// 2. Get the Apollo client from context
const client = getClient();
// 3. Execute the GET_BOOKS graphql query using the Apollo client
// -> Returns a svelte store of promises that resolve as values come in
const books = query(client, { query: GET_BOOKS });
</script>
<!-- 4. Use $books (note the "$"), to subscribe to query values -->
{#await $books}
Loading...
{:then result}
{#each result.data.books as book}
{book.title} by {book.author.name}
{/each}
{:catch error}
Error: {error}
{/await}
This doesn't integrate with the Sapper router, but we can use |
I took the same approach with _layout.svelte and not just for the svelte-apollo client. Except I put all of that setup into another module (setup.js) and imported from _layout. I just couldn't stomach having all that code actually in my _layout file. It's for layout, supposedly, but it's the only component that is a parent to the whole app. |
@jschuhr I agree. I am sure this could be done in |
@jthegedus when I try to The way I get around this is by importing the client directly into the component that calls it. |
Same issue here:
|
I used the onMount hook around the setClient(), maybe that helps. |
Cool. Can you provide an example with some code? In which file did you put the setClient()? Where and how did you call the getClient()? Did you need to use the onMount-Function or the <script context="module">-tag? Every help is much appreciated as the original-tutorial is quite confusing. |
Hi all, here's what I have working: setClient in _layout.svelte<script>
import { stores } from "@sapper/app";
import { onMount } from "svelte";
import ApolloClient from "apollo-boost";
import { setClient } from "svelte-apollo";
import Nav from "components/Nav.svelte";
import NProgress from "nprogress";
const { preloading } = stores();
onMount(async () => {
NProgress.configure({ parent: "#sapper", showSpinner: false });
preloading.subscribe(loading => {
if (loading) {
NProgress.start();
} else {
NProgress.done();
}
});
});
const client = new ApolloClient({
uri: "https://URL"
});
setClient(client);
</script>
<style>
main {
position: relative;
background-color: white;
margin: 0 auto;
box-sizing: border-box;
}
</style>
<Nav />
<main>
<slot />
</main> getClient in routes/some_route/index.svelte<script>
import { gql } from "apollo-boost";
import { getClient, query } from "svelte-apollo";
const client = getClient();
const GET_DATA = gql`
query {
...
}
`;
const data = query(client, { query: GET_DATA });
</script>
<div>
{#await $data}
<div>loading</div>
{:then result}
<div>{result}</div>
{:catch error}
<div>Error: {error}</div>
{/await}
</div> Not sure I did anything special here other than not use |
@jthegedus @phi1-h @F7dev @jschuhr @timhall I'm desperately looking to solve this problem, this is a huge show stopper in adopting GraphQL in my sapper project and would love to contribute a template project that works for Sapper. The only thing is I tried everything mentioned in all the issues across this repo and I'm still stranded and seriously tired. I'm forced to use other libraries for PoC for |
Hi @jerriclynsjohn I don't believe I have done anything special. The only thing of note was that the index route doesn't use the |
Hey there! I've just found the same issue and tried the above solutions, but they didn't help me much. After having tried them, I considered avoiding It doesn't throw anymore and it's working fine so far, but I thought I'd ask people more knowledgeable in Svelte about the consequences of such an approach. To be clear, there are some sample files:
What am I missing? What are the downsides of such approach? |
Without a proper walkthrough of setting this up, we are gonna be stuck in this boat for a while |
Greetings. I am an astronaut from the future. I've just landed on the moon via the Apollo spacecraft only to encounter this issue. |
I gave up trying to make
I'm not sure if I'm doing this correctly. I've just discovered Svelte a few weeks ago. |
Here's a related thread on the Sapper issue tracker that's also helpful: sveltejs/sapper#751 |
Is everyone here just doing client-side fetching? Or has anyone gotten this to work on the server-side as well? Is anyone using Sapper's |
I'm doing server and client-side. Am not currently using this.fetch, though that's mostly because I forgot it existed. I have a middleware that extracts the bearer token from the session (on both client and server) and adds it as an authorization header in the fetch request. This approach isn't perfect but it works reasonably well. At some point I will probably use the cache from the server request to the client by passing it in the session object. |
I had the same problem and was able to work around the limitations using the context api. Sharing is caring, so I hope this helps somebody:
|
Based on my reading of https://sapper.svelte.dev/docs#Preloading I expect
the `{ client }` return value from preload to fail serialization with deval.
It seems like returning `client` from preload will (silently?) fail
serialization of that page's preload values.
Doesn't seem to matter for the exact example you've given, but perhaps this
fact will help someone else trying to tease apart why they're seeing
preload run once on the server and then *again* in the browser in their own
application.
…On Thu, Jun 18, 2020 at 6:54 AM Pascal Clanget ***@***.***> wrote:
I had the same problem and was able to work around the limitations using
the context api. Sharing is caring, so I hope this helps somebody:
// _layout.svelte
<script context="module">
import { ApolloClient } from "apollo-client";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { RetryLink } from "apollo-link-retry";
export async function preload(page, session) {
const httpLink = createHttpLink({
// Neccessary because it is a json property which is a string
uri: `http${process.env.BACKEND_SSL ? "s" : ""}://${
process.env.SERVER_NAME
}:${process.env.SERVER_PORT}/graphql`,
credentials: "include",
fetch: this.fetch
});
const retryLink = new RetryLink({
attempts: { max: 3 },
delay: { initial: 200 }
});
const link = retryLink.concat(httpLink);
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
name: "Some Website",
version: "3.0"
});
return { client };
}
</script>
<script>
import { setContext } from "svelte";
export let client;
setContext("client", client);
</script>
// component.svelte
<script>
import { getContext } from "svelte";
const client = getContext("client");
</script>
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#9 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAABZHNLXPBMQBIVTYOB64LRXIL73ANCNFSM4HJOYRXQ>
.
|
re: Function called outside component initialization this happens with getClient and setClient because it is a svelte context which is only available at component initialization (construction) and cannot be in an event handler. see: the answer for https://stackoverflow.com/questions/60591927/svelte-user-registration-issue-with-setting-store-value Most likely what is happening is that you're calling it in an async event su as an on:click, onMount, onDestroy when it is not available. The solution to this is to store your client as a store in the context as per https://svelte.dev/tutorial/context-api. In general it should probably look something like:
|
I would just like to share this here. I made this about a year ago, and just recently updated it. |
👉 #59 👈 👀 I just use apollo/core |
Using this package with a generator like this https://github.com/ticruz38/graphql-codegen-svelte-apollo, could resolve most of your issues when working with Sapper. |
https://bjornlu.com/blog/using-apollo-client-in-sapper/ This approach works well. On the server it writes the cache into the session and on the client replaces it with a new apollo client with the cache data from the server. But the code in the link is not 100% working. Just apply the following: Add apollo client a bit differently to the session
also make sure you check if in the preload before you do a call it is on the server (preload runs on server and client)
The rest is well desribed in the link above. |
With the transition towards Svelte Kit, maybe such example would be ideal to look at as well. |
@nico-on-vacation, I have tried to set up Apollo Client in my Sapper project just like you described but sadly, all I can get is the following error: |
Please add full example svelte-apollo with sapper v3. I'm having trouble with this:
The text was updated successfully, but these errors were encountered: