robisim74/qwik-speak

Use of new t = inlineTranslate() in useVisibleTask$

Closed this issue · 4 comments

Hi! New version seems awesome
I got a warning when trying to use t in useVisibleTask$

When referencing "t" inside a different scope (useVisibleTask$), Qwik needs to serialize the value, however it is a function, which is not serializable.

What's the right way of translating in such context?

useVisibleTask$ is a different scope wrapped in a QRL: now inlineTranslate is a pure function, so you have to declare it in this new scope:

useVisibleTask$(() => {
  const t$ = inlineTranslate();
  console.log(t$('app.title'));
})

However, I find weird that you have to translate into useVisibleTask and not in the component: what is the use case?

I'm setting the zod error map like this:

export default component$(() => {
  const t = inlineTranslate();

  useVisibleTask$(() => {
    z.setErrorMap((issue, ctx) => {
      if (issue.code === ZodIssueCode.invalid_type) {
        return {
          message: t("forms.errors.required@@Requerido"),
        };
      }

      if (issue.code === ZodIssueCode.too_small && issue.type === "number") {
        return {
          message: t(
            "forms.errors.numberTooSmall@@Debe ser al menos {{minimum}}",

            {
              minimum: issue.minimum,
            },
          ),
        };
      }

      return { message: ctx.defaultError };
    });
  });

  return <Slot />;
});

I have already expressed my thoughts on translation with zod here: #61 (solution A)

I think the best and clearest solution is for the schema to do the schema, and translate into the jsx (runtimeAssets in this library exist for this reason: to be able to handle dynamic keys such as server response errors or validation errors).

Then I can't figure out a component that only runs a useVisibleTask$ (which you should use with caution) and returns a slot, but that's just my problem.

That said, if you move const t = inlineTranslate(); into useVisibleTask$ it should work: certainly in production, maybe in dev it might not return the current translation, because useVisibleTask$ is executed eagerly in the browser, before the new inlining feature in dev mode can know the current locale (let me know if you experience this behavior).

Oh, I get it. Thanks!