How to create a new element with prisma create?

Viewed 27

I'm doing a project with React, Prisma, Node and Typescript that, in short, each user will be able to create and play several quizzes and in each quiz there will be several questions. I'm currently doing the project's backend, but when I went to create a quiz function, the following error started to happen:

The type '{ title: string; description: string; }' cannot be assigned to type '(Without<QuizCreateWithoutAuthorInput, QuizUncheckedCreateWithoutAuthorInput> & QuizUncheckedCreateWithoutAuthorInput) | ... 6 more ... | (Without<...> & QuizCreateWithoutAuthorInput[])'.
   The type '{ title: string; description: string; }' cannot be assigned to type 'Without<QuizCreateWithoutAuthorInput, QuizUncheckedCreateWithoutAuthorInput> & QuizUncheckedCreateWithoutAuthorInput'.
     Property 'playedById' is missing in type '{ title: string; description: string; }', but it is mandatory in type 'QuizUncheckedCreateWithoutAuthorInput'.ts(2322)
index.d.ts(5857, 5): 'playedById' is declared here.
index.d.ts(5546, 5): The expected type comes from the 'create' property, which is declared here in the 'QuizUncheckedUpdateManyWithoutAuthorNestedInput | QuizUpdateManyWithoutAuthorNestedInput'

I made the prisma schema as follows:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model User {
  id String @id @default(uuid())

  name String @unique

  userQuizzes Quiz[] @relation("author") 
  playedQuizzes Quiz[] @relation("playedQuizzes")

  plays Play[]

  @@map("users")
}

model Quiz {
  id String @id @default(uuid())

  author User @relation("author" ,fields: [authorId], references: [id])
  playedBy User @relation("playedQuizzes",fields: [playedById], references: [id])

  title String
  description String @db.LongText
  times_played Int @default(0)
  
  authorId String
  playedById String

  questions Question[]
  plays Play[]

  @@map("challanges")
}

model Question {
  id String @id @default(uuid())

  question String @db.LongText
  answer String

  quiz Quiz @relation(fields: [quizId], references: [id])
  quizId String

  @@map("questions")
} 

model Play {
  id String @id @default(uuid())
  
  player User @relation(fields: [playerId], references: [id])
  playerId String

  result Float

  quiz Quiz @relation(fields: [quizId], references: [id])
  quizId String

  @@map("plays")
}

and so is the code in ts:

import { prisma } from "../../../prisma/client";


interface createChallangeType {
    userId: string
    title: string
    genre: string
    description: string
}


export class createChallangeUseCase {
    async execute({userId, title, description}: createChallangeType) {
        try {
            const newChallange = await prisma.user.update({
                where: {
                    id: userId
                },
                data: {
                    userQuizzes: {
                        create: {
                            title: title,
                            description: description
                        }
                    }
                }
            })

            return newChallange
        } catch (error) {
            return error
        }
    }
}
1 Answers

Prisma generates TypeScript type definitions for all of the database models and operations. It also incorporates whether a field is marked as optional into the types it generates.

These lines in your Prisma schema:

  playedBy User @relation("playedQuizzes",fields: [playedById], references: [id])
  playedById String

indicate to Prisma that playedBy is a required relationship. Since there is also no default, Prisma generates TypeScript type definitions that require either playedBy or playedById to be specified when creating new Quiz entries. The TypeScript error is indicating that with

Property 'playedById' is missing in type '{ title: string; description: string; }', but it is mandatory in type 'QuizUncheckedCreateWithoutAuthorInput'

Why is it not raising the same error for author when it's also required?

  author User @relation("author" ,fields: [authorId], references: [id])
  authorId String

That's because Prisma already knows the correct author value to use since it is an update.

const newChallange = await prisma.user.update({
  where: {
    id: userId  // <- locates a unique User record
  },
  data: {
    userQuizzes: { // <- `userQuizzes Quiz[] @relation("author")` Prisma connects on `author` because of this relation
      create: {
        title: title,
        description: description
        // <- Prisma doesn't know to connect `playedBy` since it could be a different User
      }
    }
  }
})

So to resolve it you either need to specify playedBy/playedById or update the Prisma schema to make playedBy and playedById optional.

Related