Learn how to dynamically adjust context using a server-client architecture with TRPC

Currently, I am referring to the tRPC documentation for guidance on creating a server side caller. But I'm facing a challenge in dynamically setting the value when incorporating it into my NextJS 13 pages.

In my context.ts file, you will find the following code snippet:

import { cookies } from "next/headers";
import * as jose from "jose";
import jwt from "jsonwebtoken";
import { inferAsyncReturnType } from "@trpc/server";

interface ContextUser {
    id: number;
    username: string;
    token: string;
}

export async function createContext() {
    async function getUserFromCookie(): Promise<ContextUser | null> {
        var token = cookies().get("jwt");

        if (!token?.value) return null;

        const secret = new TextEncoder().encode(process.env.JWT_SECRET);

        try {
            await jose.jwtVerify(token.value, secret);
        } catch (error) {
            return null;
        }

        const jwtPayload = jwt.decode(token.value) as any;

        return {
            id: jwtPayload.nameid,
            username: jwtPayload.unique_name,
            token: token.value,
        };
    }

    const user = await getUserFromCookie();

    return {
        user,
    };
}

export type Context = inferAsyncReturnType<typeof createContext>;

I have implemented middleware to verify the user and exported an authorized procedure:

import { TRPCError, initTRPC } from "@trpc/server";
import { Context } from "./context";

const t = initTRPC.context<Context>().create();

export const router = t.router;
export const publicProcedure = t.procedure;

const authorised = t.middleware(async ({ ctx, next }) => {
    if (!ctx.user) throw new TRPCError({ code: "UNAUTHORIZED" });

    return next();
});

export const authorisedProcedure = t.procedure.use(authorised);

In my server.ts file, I export a server client in the following manner:

import { appRouter } from "@/server";

export const trpcServerClient = appRouter.createCaller({
    user: { id: 1, username: "foo", token: "bar" },
});

Upon calling a procedure using the trpcServerClient with a valid cookie, although the token is observable within createContext, it appears that the context is not properly set-in the procedure, where ctx remains as

user: { id: 1, username: "foo", token: "bar" }
.

My confusion lies in how one can dynamically configure the context while utilizing a server client, especially given the requirement to input a value for the context in the createCaller function?

Answer №1

import { createServiceContext } from "@/server/context"
import { appRoutes } from "@/server";

export const trpcClient = appRoutes.createCaller(await createServiceContext());

(Please note that using await at the top level might necessitate modifying your tsconfig target if you are still on "es5")

Answer №2

generateCaller has been phased out in v13 and newer versions of tRPC. The updated method to achieve this task is as follows:

import { createContext } from "@server/context";
import { appService } from "@server/service";
import { trpc } from "@server/trpc";

const generateCaller = trpc.generateCallerFactory(appService);
export const clientServer = generateCaller(await createContext());

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the correct way to define the onClick event in a React component?

I have been encountering an issue while trying to implement an onClick event in React using tsx. The flexbox and button are being correctly displayed, but I am facing a problem with the onClick event in vscode. I have tried several ideas from the stack com ...

Error in typography - createStyles - 'Style<Theme, StyleProps, "root"

I'm encountering an error in a small React app. Here is a screenshot of the issue: The project uses "@material-ui/core": "4.11.3". In the codebase, there is a component named Text.tsx with its corresponding styles defined in Text.styles.tsx. The styl ...

Difficulty Determining Literal Types that Expand a Union of Basic Data Types

Below are the components and function I am working with: interface ILabel<T> { readonly label: string; readonly key: T } interface IProps<T> { readonly labels: Array<ILabel<T>>; readonly defaultValue: T; readonly onChange ...

Cheerio fails to retrieve items from the specified directory

My main goal with cheerio is to scrape the titles from this IMDb ranking: Despite following the documentation and specifying the exact HTML path for the titles, I am getting back random and confusing objects like: 'x-attribsNamespace': [Object ...

The Relationship between Field and Parameter Types in TypeScript

I am currently working on a versatile component that allows for the creation of tables based on column configurations. Each row in the table is represented by a specific data model: export interface Record { attribute1: string, attribute2: { subAt ...

The toggle-input component I implemented in React is not providing the desired level of accessibility

Having an accessibility issue with a toggle input while using VoiceOver on a Mac. The problem is that when I turn the toggle off, VoiceOver says it's on, and vice versa. How can I fix this so that VoiceOver accurately states whether the toggle is on o ...

Incorporate the Get Your Guide Widget into an Angular2 component

Currently, I am attempting to embed a "Get Your Guide" Widget within an Angular2 application. Although the script in index.html is being requested successfully, I am facing difficulties adding it to the HTML of the component. <script async defer src=" ...

When using Vue 3 in my app, I discovered that all the TypeScript files are easily accessible through the browser console

I recently completed my Vue3 js app with Typescript, and I have noticed that all the Typescript files are easily accessible for anyone to view through the Sources tab of the browser console. The code is perfectly clear and readable. Is there a method to p ...

RxJS: Understanding the issue of 'this' being undefined when used within the subscribe method

As I work on setting up a simple error notifications component and debug in Visual Studio, an issue arises within the subscribe function where 'this' is undefined. public notifications: NotificationMessage[]; constructor(notificationService: N ...

The network socket connection for the Netlify Apollo NextJS SSR client was disconnected before a secure TLS connection could be established

I've developed an application using NextJS that is currently hosted on Netlify. The API, which is a NestJS project running GraphQL, is hosted on Heroku. While in local development mode, all my SSR pages work flawlessly. However, when transitioning to ...

WebStorm is having difficulty identifying the Next.js project

I'm running into an issue with a React Next.js project that was previously functioning properly, but now it's having trouble recognizing the project and files. This means I can't search for files or find information within them. Even after ...

How can I implement a GET request in NextJS 13.4 to fetch all items or by a specific ID? Should I use Response, NextAPIResponse, or NextResponse with the latest App Router features?

What is the proper method for performing a GET request (either to retrieve all items or by a specific ID) in NextJS 13.4 using the new App Router? The old approach of handling GET requests with NextAPIRequest, NextAPIResponse, checking if (req.method === ...

Tips for troubleshooting the error message: "The relative import path "$fresh/dev.ts" is not prefaced with / or ./ or ../"

My editor is showing a TypeScript error for a Deno module I am working on. The import path "$fresh/dev.ts" should be prefixed with / or ./ or ../ I have an import_map.json file set up with the following content. { "imports": { "$fre ...

Update ngModel value following the PUT request response

I currently have a variable named dummy_value and I would like to update it using an input box. <p>{{dummy_value}}</p> <input [(ngModel)]="dummy_value" /> Upon making this change, the dummy_value updates instantly due to the two-way bin ...

Encountering an issue with the 'createObjectURL' function in URL, resulting in overload resolution failure when using npm file-saver

While working on my angular app, I encountered a situation where I needed to download user details uploaded as a Word document to my local machine using the angular app. Successfully, I was able to upload and save this data to my database, getting its byte ...

Saving the Auth0 user object in React Context for Typescript in a Next.js environment

I am working on integrating Auth0 user authentication into my React application using the useUser hook and the context API. My goal is to access the user object globally throughout the app by storing it in the userContext.tsx file: import { createContext, ...

Are you on the lookout for an Angular2 visual form editor or a robust form engine that allows you to effortlessly create forms using a GUI, generator, or centralized configuration

In our development team, we are currently diving into several Angular2< projects. While my colleagues are comfortable coding large forms directly with Typescript and HTML in our Angular 2< projects, I am not completely satisfied with this method. We ...

Exploring the world of Typescript TSX with the power of generic

Introducing JSX syntax support in Typescript opens up new possibilities. I have an expression that functions smoothly with traditional *.ts files, but encounters issues with *.tsx files: const f = <T1>(arg1: T1) => <T2>(arg2: T2) => { ...

The element you are trying to access, "noUiSlider," does not belong to the type "HTMLElement" and cannot be found

Running into a roadblock here. What mistake am I making? .... /// <reference path="../../../typings/tsd.d.ts" /> var slider:HTMLElement = document.getElementById('slider'); noUiSlider.create(slider, { start: +$input.val(), step: + ...

synchronize the exchange of information and events between two components

Just joined this platform and diving into Angular 7 coding, but already facing an issue. I've set up two components along with a service. The data is fetched by the service upon clicking a button in the searchbar component, and I aim to display it i ...