Loading data from server with SolidStart doesn't work as it should be for me

641 views Asked by At

This is my first try on building a web app, so there might be an obvious answer but I have been struggling for some hours now. Thank you in advance.

This is the code for the page this is about:

import { createServerData$ } from "solid-start/server";
import { PrismaClient } from "@prisma/client";
import { For, createEffect, createSignal, onMount } from "solid-js";
import { useRouteData } from "solid-start";

export function routeData(){
    const users = createServerData$(async ()=>{
        const prisma = new PrismaClient();
        const allusers = await prisma.user.findMany();
        console.log("all Users: ", allusers);
        await prisma.$disconnect();
        return allusers;
    });
    return users;
}

export default function Home(){
    const [users, setUsers] = createSignal();
    const [dataLoad, setDataLoad] = createSignal(false);
    const data = useRouteData<typeof routeData>();
    createEffect(()=>{
        console.log("Loading Status:"+ data.state);
        if(data.state !== 'ready') return;
        if(data() === null){
            console.log("No Data");
        }else{
            console.log("data loaded");
            setDataLoad(true);
            console.log(data()?.toString());
        }
    });
    

    return ...

I am fetching the data in the routeData() function from the server and load the data using useRouteData(). I set up an Effect to keep track of the loading Status. My assumption was that the status should at first be pending, then change and therefore trigger the effect again so it logs my data.

This does not happen though. If I open the page in my browser, i get the following console output:

Loading Status:pending

However, if i click on a link and move to another route, and then move again to the page I am talking about, i get the following output which is the one I was hoping for:

Loading Status:pending 
Loading Status:ready 
data loaded 
[object Object],[object Object]

​It would be a great help to me to understand what is going on there.

I have been trying to track down what happens using console logs as you can see above. But I can't make sense of them and am more confused now than before.

1

There are 1 answers

0
Berk Ormanlı On

First of all I need to say I'm also new to SolidJS and trying to figure out the ways to improve my skills in it. So this reply will be mostly about my own experience and stuff that I figured out on my own. If anyone with better experience and knowledge sees any wrong or missing information, please reply and let me fix it.

I was struggling with createResource like this for a few hours and but my problem was mainly because faulty usage of a for loop. Anyway, while using routeData it returns a Resource and there are few tricks to use it (I suppose?). There are components that are used to control the flow of the resource you created using routeData like and . These can be used with Signals too. They will change according to the values that are used in the component. Let me give you an example from the app I'm developing.

export default function RepoList() {
    const [repos] = createResource(async () => {
        const repoCardList: JSXElement[] = [];
        for (const repo of repoListToShow) {
            const fetchUrl = repo.replace('github.com', 'api.github.com/repos')
            
            const compToAdd = await fetch(fetchUrl, {
                method: "GET", // *GET, POST, PUT, DELETE, etc.
                headers: {
                    'Accept': 'application/vnd.github+json'
                }
            }).then((data) => data.json()).then((resp) => {
                const prop = {
                    repo_name: resp.name,
                    user: resp.owner.login,
                    description: resp.description,
                    forks: resp.forks,
                    langauge: resp.language,
                    stargazers_count: resp.stargazers_count,
                    watchers_count: resp.watchers_count,
                    avatar: resp.avatar_url
                } as RepoCardDetails
                return <RepoCard {...prop} />
            });
            repoCardList.push(compToAdd)
        }
        return repoCardList;
    });
   
    return (
        <div class="py-8 px-24 grid grid-cols-2">
            <Switch fallback={<div>Not Found</div>}>
                <Match when={repos.state === 'pending' || repos.state === 'unresolved'}>
                    Loading...
                </Match>
                <Match when={repos.state === 'ready'}>
                    {/*@once*/ repos()}
                </Match>
                <Match when={repos.state === 'errored'}>
                <div>Errored</div>
                </Match>
            </Switch>
        </div>
    )
}

With the usage of Switch and Match components, they are basically switch/case statements, I've managed to show all repo cards that I've fetched using the GitHub API and exposed it with createResource. This way SolidJS handles all the reactive changes that are happening caused by async routeData function. This way you won't need to keep track the status of your routeData with createEffect.