Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use fetch in a Sapper project outside of routes?

Tags:

svelte

sapper

In Sapper it's possible to use this.fetch in the preload() function inside <script context="module">. Sapper then figures out whether to use the client or server version of fetch.

<script context="module">
    export async function preload() {
        const res = await this.fetch(`something.json`);
    }
</script>

Writing all your requests in your routes doesn't scale well so it becomes a necessity to create an api service to do something like:

<script context="module">
    import {getJson} from 'api';

    export async function preload() {
        const res = await getJson();
    }
</script>

This creates a problem since outside of the preload() function there is no this context provided by Sapper and hence no this.fetch available when running in the Node context (when loading the first page of the application and doing SSR). Afterwards all requests are made from the browser so regular fetch is available.

A solution could be to use an HTTP client for Node like node-fetch in the api service and then determine at runtime with process.browser if we need to use fetch or node-fetch.

Is there a better way to overcome this Sapper limitation?

like image 250
Pier Avatar asked Oct 16 '22 04:10

Pier


2 Answers

The solution you came up with is the most common one. An alternative would be to pass this.fetch as an argument along others to the the getJson method:

<script context="module">
    import {getJson} from 'api';

    export async function preload() {
        const res = await getJson(this.fetch);
    }
</script>
like image 137
Stephane Vanraes Avatar answered Oct 23 '22 23:10

Stephane Vanraes


this.fetch is meant to be used only in routes (think asyncData in Nuxt). Using Axios is a common solution too, as it allows to write code that execute the same in both environments without patching fetch (like you would with node-fetch).

like image 1
Etienne Avatar answered Oct 23 '22 23:10

Etienne