When I try to access prisma I get this error I am using fastify. I am new to both, fastify and GQL
"type": "GraphQLError",
"message": "Cannot read properties of undefined (reading 'user')",
"stack":
TypeError: Cannot read properties of undefined (reading 'user')
This is how i am passing context
import AltairFastify from "altair-fastify-plugin";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import mercurius from "mercurius";
import mercuriusCodegen from "mercurius-codegen";
import { makeSchema } from "nexus";
import { schemaTypes } from "./graphql/index";
import path from "path";
const buildContext =
(fastify: FastifyInstance) =>
async (req: FastifyRequest, _reply: FastifyReply) => ({
req,
prisma: fastify.prisma,
});
const schema = makeSchema({
types: schemaTypes,
outputs: {
schema: `${__dirname}/generated/schema.graphql`,
typegen: `${__dirname}/generated/typings.ts`,
},
contextType: {
module: path.join(process.cwd(), "src", "graphql", "context.ts"),
export: "Context",
},
});
export async function initGraphql(app: FastifyInstance) {
try {
await app.register(mercurius, {
schema,
graphiql: false,
ide: false,
path: "/graphql",
allowBatchedQueries: true,
context: buildContext(app),
});
await app.register(AltairFastify, {
path: "/altair",
baseURL: "/altair/",
// 'endpointURL' should be the same as the mercurius 'path'
endpointURL: "/graphql",
});
await mercuriusCodegen(app, {
// Commonly relative to your root package.json
targetPath: `${__dirname}/generated/graphql.ts`,
});
} catch (err: unknown) {
app.log.error(err);
}
}
this is my prisma plugin
import fp from "fastify-plugin";
import { PrismaClient } from "@prisma/client";
/**
* Prisma plugin for Fastify.
*/
export default fp(async (fastify) => {
// Initialize Prisma client
const prisma = new PrismaClient();
// Decorate Fastify with Prisma client instance
fastify.decorate("prisma", prisma);
// Add a hook to close the Prisma client when Fastify is shutting down
fastify.addHook("onClose", async (instance) => {
await prisma.$disconnect();
});
fastify.log.info("Prisma started...");
});
I am also using Nexus.js
export const UserMutation = mutationType({
definition(t) {
t.field("createUser", {
type: UserType,
args: {
firstName: nonNull(stringArg()),
lastName: nonNull(stringArg()),
phoneNumber: nonNull(stringArg()),
otp: nonNull(stringArg()),
},
resolve: async (_parent, args, { req, prisma }) => {
console.log(prisma);
const { jwt } = req.server;
const user = await prisma.user.create({
data: args,
select: {
id: true,
... // More fields
},
});
const token = jwt.signToken(user.id);
return { ...user, token };
},
});
},
});
Here prisma
is undefined, I tried logging a console and prisma is undefined.
Am i doing something wrong? I tried directly consoling the prisma int the prisma plugin and it works there, without error even if i directly use prisma client in the resolver it is successful.
I tried using the prismaclient directly inside the resolver, passing in different ways for example directly placing the new PrismaClient
instead of fastify.prisma
in the buildContext
nothing works.
NOTE: I am using this template https://github.com/jellydn/fastify-starter
I had been trying to solve an issue for two days, and after waiting for hours, I finally found the solution.
The problem was that my autoload function was in app.ts, and I was calling it in server.ts. While Prisma was accessible to fastify in app.ts, it was not accessible in server.ts. As a beginner in fastify, I didn't want to waste any more time on this issue, as I was trying to build something quickly rather than learning.
To resolve the issue, I used 'then' to start the graphql server only after all the plugins had loaded. Here is the code I used:
// Instantiate Fastify with some config
const server = Fastify({
logger: configureLogging(environment),
});
void server.register(env);
void server.register(prisma);
// Use fastify-autoload to load all plugins in the 'plugins' folder
void server
.register(fastifyAutoload, {
dir: join(__dirname, "plugins"),
ignoreFilter(path) {
return ["/env.ts", "/index.ts", "/prisma.ts"].includes(path);
},
})
.then(() => {
// Init graphql
void initGraphql(server);
// Init Swagger
void initSwagger(server);
});
I hope that helps!