outis99
outis993y ago

Mutation type issue

I'm trying to mutate something like this with tRPC and Prisma
const updateColumn = trpc.project.update.useMutation();
updateColumn.mutate({ colId: list.id, cards: list.cards })
const updateColumn = trpc.project.update.useMutation();
updateColumn.mutate({ colId: list.id, cards: list.cards })
list.id is just a string but list.cards has a type of Card[] which I'm importing from a file Prisma auto-generated from my schema Then on my backend
update: protectedProcedure
.input(
z.object({
colId: z.string(),
cards: //what do I put here?
})
)
.mutation(async ({ input, ctx }) => {
const result = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: input.cards, //type error
},
});

console.log(result, "?dbresult");
})
update: protectedProcedure
.input(
z.object({
colId: z.string(),
cards: //what do I put here?
})
)
.mutation(async ({ input, ctx }) => {
const result = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: input.cards, //type error
},
});

console.log(result, "?dbresult");
})
I tried putting something like z.array(z.object({})) but obviously that doesn't work and it shows this error
20 Replies
volks
volks3y ago
@Outis I can pinch in with what I'd do, but you either define the types manually, or you can use something like https://github.com/omar-dulaimi/prisma-zod-generator and then generate the zod schema based on the card
GitHub
GitHub - omar-dulaimi/prisma-zod-generator: Prisma 2+ generator to ...
Prisma 2+ generator to emit Zod schemas from your Prisma schema - GitHub - omar-dulaimi/prisma-zod-generator: Prisma 2+ generator to emit Zod schemas from your Prisma schema
volks
volks3y ago
But if the card is a simple type then just manually create it
outis99
outis99OP3y ago
This is really useful but my problem has evolved even further lol My front end receives an array of objects and I just want to overwrite/update my previous array of objects inside my cards property I've tried plenty of solutions, posted on the slack prisma help channel but nothing yet and I'm really contemplating if the switch to trcp/prisma is worth it
volks
volks3y ago
What exactly is the issue that prevents you from updating the previous array?
outis99
outis99OP3y ago
I just don't understand the prisma update syntax for it
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: {},
},
});
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: {},
},
});
This is where I get to and I truly have tried so much stuff
volks
volks3y ago
You need to update all the cards? Or you just need to update a single entity with the cards?
outis99
outis99OP3y ago
I simply want to update the order of the cards So what I'm doing is reorder my cards in my front end and send it to my backend
volks
volks3y ago
Like this?
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: CARDS_YOU_GET_FROM_FRONTEND,
},
});
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: CARDS_YOU_GET_FROM_FRONTEND,
},
});
outis99
outis99OP3y ago
You would think it works like that but doesn't
volks
volks3y ago
Are you getting any errors or?
outis99
outis99OP3y ago
volks
volks3y ago
Yeah well it says that the type is invalid Your cards you got from the frontend seems to be incorrect Can you print typeof cards[0]?
outis99
outis99OP3y ago
export type Card = {
id: string
title: string
index: number
description: string | null
columnId: string
}
export type Card = {
id: string
title: string
index: number
description: string | null
columnId: string
}
This is the type It's exactly the same, I don't it's a type issue I think it has to do with how updating records works in Prisma when you also have relations
volks
volks3y ago
Yeah I'd say this is not related to tRPC but rather prisma, their error message is horrible so I cant decrypt much more from it IS there any more info in the error?
outis99
outis99OP3y ago
Argument cards: Got invalid value
[
{
id: 'cl9ego52z0001wb0k7ueqykh7',
title: 'Test 2',
index: 1,
description: null,
columnId: 'cl9eftdjm0002wbucv6rjulj0'
},
{
id: 'cl9eg8r4r0000wb0kd9j6cy17',
title: 'Test',
index: 0,
description: null,
columnId: 'cl9eftdjm0002wbucv6rjulj0'
}
]
on prisma.updateOneColumn. Provided List<Json>, expected CardUpdateManyWithoutColumnNestedInput:
type CardUpdateManyWithoutColumnNestedInput {
create?: CardCreateWithoutColumnInput | List<CardCreateWithoutColumnInput> | CardUncheckedCreateWithoutColumnInput | List<CardUncheckedCreateWithoutColumnInput>
connectOrCreate?: CardCreateOrConnectWithoutColumnInput | List<CardCreateOrConnectWithoutColumnInput>
upsert?: CardUpsertWithWhereUniqueWithoutColumnInput | List<CardUpsertWithWhereUniqueWithoutColumnInput>
createMany?: CardCreateManyColumnInputEnvelope
set?: CardWhereUniqueInput | List<CardWhereUniqueInput>
disconnect?: CardWhereUniqueInput | List<CardWhereUniqueInput>
delete?: CardWhereUniqueInput | List<CardWhereUniqueInput>
connect?: CardWhereUniqueInput | List<CardWhereUniqueInput>
update?: CardUpdateWithWhereUniqueWithoutColumnInput | List<CardUpdateWithWhereUniqueWithoutColumnInput>
updateMany?: CardUpdateManyWithWhereWithoutColumnInput | List<CardUpdateManyWithWhereWithoutColumnInput>
deleteMany?: CardScalarWhereInput | List<CardScalarWhereInput>
}
Argument cards: Got invalid value
[
{
id: 'cl9ego52z0001wb0k7ueqykh7',
title: 'Test 2',
index: 1,
description: null,
columnId: 'cl9eftdjm0002wbucv6rjulj0'
},
{
id: 'cl9eg8r4r0000wb0kd9j6cy17',
title: 'Test',
index: 0,
description: null,
columnId: 'cl9eftdjm0002wbucv6rjulj0'
}
]
on prisma.updateOneColumn. Provided List<Json>, expected CardUpdateManyWithoutColumnNestedInput:
type CardUpdateManyWithoutColumnNestedInput {
create?: CardCreateWithoutColumnInput | List<CardCreateWithoutColumnInput> | CardUncheckedCreateWithoutColumnInput | List<CardUncheckedCreateWithoutColumnInput>
connectOrCreate?: CardCreateOrConnectWithoutColumnInput | List<CardCreateOrConnectWithoutColumnInput>
upsert?: CardUpsertWithWhereUniqueWithoutColumnInput | List<CardUpsertWithWhereUniqueWithoutColumnInput>
createMany?: CardCreateManyColumnInputEnvelope
set?: CardWhereUniqueInput | List<CardWhereUniqueInput>
disconnect?: CardWhereUniqueInput | List<CardWhereUniqueInput>
delete?: CardWhereUniqueInput | List<CardWhereUniqueInput>
connect?: CardWhereUniqueInput | List<CardWhereUniqueInput>
update?: CardUpdateWithWhereUniqueWithoutColumnInput | List<CardUpdateWithWhereUniqueWithoutColumnInput>
updateMany?: CardUpdateManyWithWhereWithoutColumnInput | List<CardUpdateManyWithWhereWithoutColumnInput>
deleteMany?: CardScalarWhereInput | List<CardScalarWhereInput>
}
Some more that was missing but I don't think it's of any use I also tried something like this
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: {
set: input.cards,
},
},
});
const column = await ctx.prisma.column.update({
where: {
id: input.colId,
},
data: {
cards: {
set: input.cards,
},
},
});
But set only takes exactly one arguement, the id
volks
volks3y ago
Hopefully someone with more knowledge will be able to help out, I can only think that the type contained in the array cards is not appropriate but I dont understand their error message...
outis99
outis99OP3y ago
Well I hope so too, appreciate the help This is what I came up with
updateColumn: protectedProcedure
.input(
z.object({
colId: z.string(),
cards: z.any(),
})
)
.mutation(async ({ input, ctx }) => {
for (let i = 0; i < input.cards.length; i++) {
const card = input.cards[i] as Card;

const _card = await ctx.prisma.card.update({
where: {
id: card.id,
},
data: {
index: i,
},
});
}

console.log("input cards?", input.cards);
}),
updateColumn: protectedProcedure
.input(
z.object({
colId: z.string(),
cards: z.any(),
})
)
.mutation(async ({ input, ctx }) => {
for (let i = 0; i < input.cards.length; i++) {
const card = input.cards[i] as Card;

const _card = await ctx.prisma.card.update({
where: {
id: card.id,
},
data: {
index: i,
},
});
}

console.log("input cards?", input.cards);
}),
It works but it has to update each index individually
volks
volks3y ago
So every card is its own entity? Its a bit different from the code you listed above But if it works great, update me if someone on the prisma side replies
outis99
outis99OP3y ago
Yes it is, this is my schema
model Project {
id String @id @default(cuid())
updatedAt DateTime @updatedAt @default(now())
slug String
title String

userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
columns Column[]

@@unique([slug, userId])
}

model Column {
id String @id @default(cuid())
title String

projectId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
cards Card[]
}

model Card {
id String @id @default(cuid())
title String
index Int
description String?

columnId String
column Column @relation(fields: [columnId], references: [id], onDelete: Cascade)
}
model Project {
id String @id @default(cuid())
updatedAt DateTime @updatedAt @default(now())
slug String
title String

userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
columns Column[]

@@unique([slug, userId])
}

model Column {
id String @id @default(cuid())
title String

projectId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
cards Card[]
}

model Card {
id String @id @default(cuid())
title String
index Int
description String?

columnId String
column Column @relation(fields: [columnId], references: [id], onDelete: Cascade)
}
volks
volks3y ago
Are the cards in the column embedded or via a reference? Not sure how Prisma works or what driver youre using Basically you can use a transaction and bulk insert all the cards and then update the column with the newly inserted cards But I cant give you the exact implementation as I am not familiar with the technology unfortunately