Vihren Pironski
Vihren Pironski

Reputation: 13

Setting up SvelteKit CRUD routing with [id] parameter

I am working on a Svelte - Java Spring - MongoDB CRUD app, were i need to handle the 4 HTTP Requests : GET, POST, DELETE, UPDATE.

I have the following problem. When i try to access the following url : http://localhost:5173/get it gives me all my objs (list of paintings) because my src/lib/api.js get a json of paintings from http://localhost:5173/api/get. The problem lies when i try to access a single painting by Id, where if i try to go to url : http://localhost:5173/get/66465b054183ec71756ed694 it gives me error 404 : not found. But when i tried to access http://localhost:5173/api/get/66465b054183ec71756ed694 it returns the correct object.

So i have narrowed down the problem to the communication between the api and the src/route/get/[id].svelte. So in search of help I will provide the src folder structure and the files src/lib/api.js , svelte.config.js, src/routes/get/+page.svelte & src/routes/get/[id].svelte.

I have tried forums and AI for help, but just found myself going in a circle. Please Help!

App Structure:

src
├── app.html
├── lib
│   ├── api.js
│   └── index.js
└── routes
    ├── +layout.svelte
    ├── +page.svelte
    ├── delete
    │   └── +page.svelte
    ├── get
    │   ├── +page.svelte
    │   └── [id].svelte
    ├── post
    │   └── +page.svelte
    └── update
        └── +page.svelte

api.js:

export async function getAllPaintings() {
    const response = await fetch('/api/get');

    if (!response.ok) {
        throw new Error('Failed to fetch paintings');
    }
    return await response.json();
}

export async function getPaintingById(id) {
    const response = await fetch(`/api/get/${id}`);

    if (!response.ok) {
        throw new Error('Failed to fetch painting');
    }
    return await response.json();
}

get/+page.svelte:

<script>
    import { onMount } from 'svelte';
    import { getAllPaintings } from '$lib/api.js';

    let paintings = [];

    onMount(async () => {
        try {
            const response = await getAllPaintings();
            console.log(response); // Log the response to inspect its structure
            paintings = response; // Assuming response is an array of paintings
        } catch (error) {
            console.error('Error fetching paintings:', error);
        }
    });
</script>

<h1>Paintings</h1>

<ul>
    {#each paintings as painting}
        <li>{painting.name}</li>
    {/each}
</ul>

and get/[id].svelte :

<!-- [id].svelte -->
<script>
    import { onMount } from 'svelte';
    import { getPaintingById } from '$lib/api';
    import { page } from '$app/stores';

    let painting = null;
    let error = null;

    onMount(async () => {
        try {
            const id = $page.params['*'];

            painting = await getPaintingById(id);
        } catch (err) {
            console.error('Error fetching painting:', err);
            error = err.message;
        }
    });
</script>

{#if error}
    <p>{error}</p>
{:else if !painting}
    <p>Loading...</p>
{:else}
    <h1>{painting.name}</h1>
    <p>{painting.description}</p>
    <!-- Add more painting details as needed -->
{/if}

svelte.config.js :

import adapter from '@sveltejs/adapter-auto';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    debug: true,
    kit: {
        adapter: adapter()
    }
};
export default config;

I you need any more information I'd be happy to provide!

I have tried $paga.params.id & $page.params I have also tried adding numerous console.logs in both the api function and the [id].svelte but none of them responded. Tried changing svelte.config by adding paths but it just doesn't let the server run so I left it empty.

Upvotes: 1

Views: 559

Answers (2)

Amal B Nair
Amal B Nair

Reputation: 54

To solve this problem I am suggesting changing the structure of your project like below.

src
├── app.html
├── lib
│   ├── api.js
│   └── index.js
└── routes
    ├── +layout.svelte
    ├── +page.svelte
    ├── delete
    │   └── +page.svelte
    ├── get
    │   ├── +page.svelte
    │   └── [id]
    |     |__+page.server.js
    |     |__+page.svelte
    ├── post
    │   └── +page.svelte
    └── update
        └── +page.svelte

add a slug folder for a specific painting and access that specific painting id in the page.server.js load function and using that id you can do the rest of your code

example code

export function load({params}){
    let painting_id= params.id;
    return {painting_id};
}

Upvotes: 3

brunnerh
brunnerh

Reputation: 184607

That's not how route parameters work, you need a directory called [id] containing a +page.svelte. See routing docs.

Upvotes: 1

Related Questions