solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

createServerData$ runs twice

Open viridia opened this issue 3 years ago • 1 comments

I wanted to add a 'viewCount' to my app showing the number of times a given thread was viewed. The approach I took was to update the database when fetching the list of messages in createServerData$:

export function routeData({ params }) {
  return createServerData$(
    async ([, id], { request }) => {
      const session = await getServerSession(request);
      await runQuery<{ thread: Post }>({
        operationName: 'BumpCount',
        query: threadQuery,
        session,
        variables: {
          postId: Number(id),
        },
      });
      return runQuery<{ thread: Post }>({
        operationName: 'ThreadQuery',
        query: threadQuery,
        session,
        variables: {
          postId: Number(id),
        },
      });
    },
    { key: () => ['thread', params.postId] }
  );
}

The problem I have, however, is that this code runs twice for every page that is rendered, which means that the view count gets bumped by 2.

It seems really inefficient to be double-fetching records from the database. The 'ThreadQuery' is a particularly expensive query because it's fetching an entire thread (including all the user reactions and comments), and it doesn't make much sense to fetch the data twice.

viridia avatar Nov 17 '22 19:11 viridia

Seems like the fetcher is being re-executed on the client even though the key is the same. This only happens when createRouteData is used with a function as the key. This does not happen when using a static key or when using a function key with createResource. https://stackblitz.com/edit/create-route-data-fn-key-bug?file=src%2Froutes%2Findex.tsx

ghalle avatar Nov 18 '22 21:11 ghalle