Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protected$ hoists useAsync calls to a different scope from dependencies #145

Open
jtmueller opened this issue Dec 5, 2024 · 1 comment

Comments

@jtmueller
Copy link

jtmueller commented Dec 5, 2024

I'm trying to set up a URL-param-driven protected page, but it seems like protected$ is rewriting working code into not-working code. Specifically, I have a createAsync call that depends on a value in the local scope (the params) but when protected$ rewrites that code, that call gets hoisted to a different scope in which the params don't exist, causing a runtime error.

I'm fairly new to SolidStart, am I approaching this wrong, or is this a bug?

Route with optional parameter:
events/[[page]].tsx

Original version of that code:

import { protected$ } from '@solid-mediakit/auth';
import { Title } from '@solidjs/meta';
import { createAsync, query, useParams } from '@solidjs/router';
import { For, Suspense, createMemo } from 'solid-js';
import { events } from '~/lib/server/db';

const pageSize = 10;

const getEvents = query(async (page?: number) => {
  'use server';
  return await events.getRecentEvents(page, pageSize);
}, 'events');

export const route = {
  preload: () => getEvents(),
};

export default protected$(function Events(session$) {
  const params = useParams();
  const page = createMemo(() => {
    const parsed = Number.parseInt(params.page);
    if (Number.isNaN(parsed)) {
      return 0;
    }
    return parsed;
  });
  const events = createAsync(() => getEvents(page()));

  return (...);
});

As you can see, events depends on the page memo, which depends on params.

Same code, as rewritten by protected$ gets a page is not defined error, because page is now in a different scope from the code that depends on it. Is there a different way for my createAsync code to reference URL parameters that I should be using?

import { authOptions } from "~/lib/server/auth";
import { Show } from "solid-js";
import { getSession } from "@solid-mediakit/auth";
import { getRequestEvent } from "solid-js/web";
import { protected$ } from '@solid-mediakit/auth';
import { Title } from '@solidjs/meta';
import { createAsync, query, useParams } from '@solidjs/router';
import { For, Suspense, createMemo } from 'solid-js';
import { events } from '~/lib/server/db';
const _$$getUser = query(async () => {
  'use server';

  const event = getRequestEvent();
  const session = await getSession(event.request, authOptions);
  if (!session) {
    throw redirect("/login");
  }
  return session;
}, "media-user");
const getEvents = query(async page => {
  'use server';

  return await events.getRecentEvents(page, 10);
}, 'events');
export const route = {
  preload: () => getEvents()
};

export default () => {
  const events = createAsync(() => getEvents(page())); // <-- not here!
  const _$$session = createAsync(() => _$$getUser(), {
    deferStream: true
  });
  const _$$RenderProtected = () => {
    const params = useParams();
    const page = createMemo(() => {
      const parsed = Number.parseInt(params.page);
      if (Number.isNaN(parsed)) {
        return 0;
      }
      return parsed;
    });                                         // <-- should be here
    return (...);
  };
  return <Show when={_$$session()?.user}><_$$RenderProtected /></Show>;
};
@vincehi
Copy link
Contributor

vincehi commented Dec 10, 2024

I have a same issue,
this code not work :

export default protected$((session$) => {
	const [currentPage, setCurrentPage] = createSignal(1);
  const data = createAsync(
		() => getDataProtectedQuery({ page: currentPage() }
	);
  return (
    <main>hello</main>
  )
}, '/login')

currentPage is not defined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants