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

Enhancing Error Handling in Node.js with TypeScript Typing

Currently, I am working with NodeJs/express and Typescript. When making a request, the compiler automatically understands the type of (req, res), requiring no additional action on my part. UserRouter.post('/user/me/avatar', avatar, async (req, ...

What is the process for implementing custom color props with Material-UI v5 in a React TypeScript project?

Looking to enhance the MUI Button component by adding custom color props values? I tried following a guide at , but encountered errors when trying to implement it in a custom component. The custom properties created in createPalette.d.ts did not work as ex ...

JavaScript Looping through multiple files for upload will return the last file in the series

I'm currently working on implementing a multiple file upload feature using JavaScript. Within my HTML, I have the following input: <input type="file" (change)="fileChange($event,showFileNames)" multiple /> When the onChange event is triggere ...

Dispatching an asynchronous function error in React with TypeScript and Redux - the parameter type is not assignable to AnyAction

Currently, I am in the process of developing a web application that utilizes Firebase as its database, along with Redux and TypeScript for state management. Within my code, I have a dispatch function nested inside a callback function like so: export const ...

Exploring multiple states within an interval function in React Native

I'm struggling to find the right words for this question. I've encountered an issue where I need to constantly check and update a complex state object within an interval loop in my program. To simplify, let's say it consists of just a counte ...

The identifier "id" is not a valid index for this type

The code snippet below demonstrates the similarities and differences between the functions addThingExample2 and addThing. While addThingExample2 directly uses the union type Things, addThing utilizes a generic parameter THING extends Thing. The expression ...

Typescript: Utilizing a generic array with varying arguments

Imagine a scenario where a function is called in the following manner: func([ {object: object1, key: someKeyOfObject1}, {object: object2, key: someKeyOfObject2} ]) This function works with an array. The requirement is to ensure that the key field co ...

What is the process of personalizing a DaisyUI theme in Tailwind with TypeScript?

I am trying to tailor an existing DaisyUI theme using my tailwind.config.ts file for my Next.js project. Although the DaisyUI documentation only provides examples in JavaScript (text), I want to customize it within my TypeScript environment. Below is a s ...

How can I incorporate multiple quality sources into a flowplayer using Angular?

Is there a way to add multiple sources with different qualities like 1080p, 720p etc.? Thank you in advance. flowplayer('#my_player', { src: '../assets/videos/video_1080p.mp4', // title: 'This is just demo&apo ...

Implementing server side authentication with Laravel Breeze and Next.js

I recently set up a new project using Laravel Breeze and Next.js. I followed the official Laravel boilerplate found at https://github.com/laravel/breeze-next. The setup is working well, but I'm wondering if there's a way to verify user authentica ...

Properly specifying the data type for a generic type variable within a function in TypeScript

As I work on my express project, I am currently coding a function called route. const morph = (params: Function[]) => (req: Request) => params.map(f => f(req)) const applyTransformers = (transformers: Function[]) => (response: any) => { ...

Exploring the benefits of using TypeScript with Angular2 for HTTP

I have a locally stored "region.json" file containing the following data: { "regionId":1, "region":"CAN" }, { "regionId":2, "region":"CEN" } Additionally, I have an "enviroment-app.component.ts" file structured as follows : import {Component, ...

Simulating Express Requests using ts-mockito in Typescript

Is there a way to simulate the Request class from Express using ts-mockito in typescript? I attempted the following import { Request, Response } from "express"; const request = mock(Request); const req: Request = instance(request); but encou ...

Getting data from an API with authorization in Next.js using axios - a step-by-step guide

click here to view the image user = Cookies.get("user") I'm having trouble accessing this pathway. I stored user data, including the token, using cookies. Please assist me with this issue. ...

Error occurred during Next.js build: SyntaxError was thrown due to an unexpected token "'<'"

Encountering multiple console errors during Next.js build preview using Netlify GitHub integration, rendering the site unusable: webpack-211c438de79acdca.js:1 Uncaught SyntaxError: Unexpected token '<' framework-715a76d8b0695da7.js:1 Uncaught ...

Adding connected types to a list using Typescript

Question regarding Typescript fundamentals. In my code, I have a list that combines two types using the & operator. Here is how it's initialized: let objects: (Object & number)[] = []; I'm unsure how to add values to this list. I attem ...

Steps for wrapping a class with a higher order component

Is it feasible to encapsulate a class component within a higher order component (HOC) that is also a class? import React, { Component } from "react"; import { View } from "react-native"; import { Toast } from "react-native-easy-toast"; const withToast = ...

In Next.js, the Typescript compiler does not halt when an error occurs

I am looking to incorporate Next.js with TypeScript into my project. I followed the official method of adding TypeScript to Next.js using npx create-next-app --typescript. Everything seemed fine, but when a TypeScript error occurs (e.g. const st: string = ...

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 ...

I require the ability to modify cellEditor parameters in real-time

How can a value be passed to cellEditorParams after the user double clicks on a grid row? The application triggers a service call on row click and the response needs to be sent to cellEditorParams. ...