denoland / fresh

The next-gen web framework.
https://fresh.deno.dev
MIT License
12.07k stars 616 forks source link

Data passed with `ctx.render` to async route is `undefined` #2435

Closed imblowfish closed 2 months ago

imblowfish commented 2 months ago

Fresh version 1.6.8 Deno version 1.43.5

Hello, I tried to do the same thing as in this blog https://deno.com/blog/setup-auth-with-fresh

import type { Handlers, PageProps } from "$fresh/server.ts";
import { getCookies } from "std/http/cookie.ts";

interface Data {
  isAllowed: boolean;
}

export const handler: Handlers = {
  GET(req, ctx) {
    const cookies = getCookies(req.headers);
    return ctx.render!({ isAllowed: cookies.auth === "bar" });
  },
};

export default function Home({ data }: PageProps<Data>) {
  return (
    <div>
      <div>
        You currently {data.isAllowed ? "are" : "are not"} logged in.
      </div>
    </div>
  );
}

And my code looks like this

interface AuthData {
  isAllowed: boolean;
}

export const handler: Handlers = {
  GET(req, ctx) {
    const cookies = getCookies(req.headers);
    return ctx.render({
      isAllowed: cookies.auth === "bar"
    } satisfies AuthData);
  },
};

export default async function Home(props: PageProps<AuthData>) {
   console.log(props.data);
   ...
}

And in the result I see that props.data is undefined

But if I'll remove async from the Home like this:

interface AuthData {
  isAllowed: boolean;
}

export const handler: Handlers = {
  GET(req, ctx) {
    const cookies = getCookies(req.headers);
    return ctx.render({
      isAllowed: cookies.auth === "bar"
    } satisfies AuthData);
  },
};

export default function Home(props: PageProps<AuthData>) {
   console.log(props.data);
   ...
}

then I can see { isAllowed: false } as expected

imblowfish commented 2 months ago

Whoops, my bad Found in the documentation https://fresh.deno.dev/docs/concepts/routes that route parameters should be rewritten to

export default async function Home(req: Request, ctx: RouteContext) {
  console.log(ctx.data);
}