Aman
Aman

Reputation: 417

How do I fetch and read the correct JSON file for my Sveltekit blog?

I have JSON files which contain the data for my posts that are in src/data/posts/ . I'm trying to create pages for each of those posts. This is my structure:

[projects]
|---[project].svelte
|---index.svelte

index.svelte contains code that lists all my posts. In [project].svelte, I would like to render the content of the relevant post. I have tried this:

<script context="module">
// All posts are contained in src/data/posts
// First, read the page.params.project and find the matching
// file name and read the data from that file.
export async function load({ page, fetch }) {
    const slug = page.params.project;
    let post;
    const url = `/src/data/posts/${slug}.json`
    post = await fetch(url)
    console.log(post)
}
</script>

However, this is not getting my JSON file. I get the following response:

500
Unexpected token < in JSON at position 0
SyntaxError: Unexpected token < in JSON at position 0

I console logged the response and it was this:

[0] Response {
[0]   size: 0,
[0]   [Symbol(Body internals)]: {
[0]     body: <Buffer 3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 0a 3c 68 74 6d 6c 20 6c 61 6e 67 3d 22 65 6e 22 3e 0a 20 20 3c 68 65 61 64 3e 0a 20 20 20 20 0a 0a 09 09 ... 59964 more bytes>,
[0]     boundary: null,
[0]     disturbed: false,
[0]     error: null
[0]   },
[0]   [Symbol(Response internals)]: {
[0]     type: 'default',
[0]     url: undefined,
[0]     status: 404,
[0]     statusText: '',
[0]     headers: {
[0]       'content-type': 'text/html',
[0]       'permissions-policy': 'interest-cohort=()'
[0]     },
[0]     counter: undefined,
[0]     highWaterMark: undefined
[0]   }
[0] }

Can I not use fetch this way? How else do I do this? What would be the proper way to get my post?

Upvotes: 1

Views: 3476

Answers (3)

Joe Krump
Joe Krump

Reputation: 121

The path to the file I was trying to fetch: src/routes/posts/index.json.ts

What I had before (which was giving me an error):

500 Unexpected token < in JSON at position 0 SyntaxError: Unexpected token < in JSON at position 0

<script context="module" lang="ts">
  import type { Load } from "@sveltejs/kit";

  export const load: Load = async ({ fetch, url }) => {
    const res = await fetch("../routes/posts/index.json");
    return { props: { posts: await res.json() } };
  };
</script>

What I had after (fixed):

<script context="module" lang="ts">
  import type { Load } from "@sveltejs/kit";

  export const load: Load = async ({ fetch, url }) => {
    const res = await fetch("/posts.json");
    return { props: { posts: await res.json() } };
  };
</script>

I ended up solving this after reading the updated Sveltekit docs here

Upvotes: 0

Aman
Aman

Reputation: 417

Since fetch only works for external servers, I used dynamic imports to solve this problem. The same code is now written as:

<script context="module">
    export async function load({ page }) {
        try {
            const Post = await import(`../../data/posts/${page.params.project}.json`);
            console.log(Post);
            return {
                // Data passed into svelte component
                props: {
                    Post:Post.default
                }
            };
        } catch (e) {
            return {
                props: {
                    Post: {
                        headling: "404",
                        content: "Page not found"
                    }
                }
            };
        }
    }
</script>

And I can make Posts available like so:

<script>
export let Post;
</script>

This gives me access to the JSON key-value pairs (like Post.title).

Upvotes: 1

OmG3r
OmG3r

Reputation: 1811

You need to convert your fetch response into JSON.

this can be done using .json()

<script context="module">
// All posts are contained in src/data/posts
// First, read the page.params.project and find the matching
// file name and read the data from that file.
export async function load({ page, fetch }) {
    const slug = page.params.project;
    let post;
    const url = `/src/data/posts/${slug}.json`
    const resp = await fetch(url) /* added this line */
    post = await resp.json() /* added this line */
    console.log(post)
}
</script>

Upvotes: 1

Related Questions