I'm trying to seed sql database using a seed script. My project Next.js with TypeScript, Faker.js, Prisma ORM with Neon PostgreSQL database setup.
schema file
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Product {
id String @id @default(cuid())
name String @unique @db.VarChar(50)
imageUrl String? @default("placeholder.png")
size String @db.Char(1)
color String @db.VarChar(10)
price Decimal? @default(0.00) @db.Money
available Boolean? @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
seed script
// /prisma/seed.ts
import { faker } from "@faker-js/faker";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
const SIZES = ["S", "M", "L"] as const;
const COLORS = ["white", "beige", "blue", "green", "purple"] as const;
async function main() {
Array.from({ length: 50 }).map(async (_, i) => {
await prisma.product.createMany({
data: {
name: `${
COLORS[i].slice(0, 1).toUpperCase() + COLORS[i].slice(1)
} shirt ${i}`,
imageUrl: `/assets/products/${COLORS[i]}_${i + 1}.png`,
size: faker.helpers.arrayElement(SIZES),
color: faker.helpers.arrayElement(COLORS),
price: faker.commerce.price({
min: 10,
max: 50,
dec: 2,
// symbol: "$",
// fractionDigits: 2,
}),
available: faker.helpers.arrayElement([true, false]),
},
});
});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
If I try to upload more than 5 products
Array.from({ length: 50 }).map(async (_, i) => {...}
,
it returns TypeError: Cannot read properties of undefined (reading 'slice')
I'm confused about, if the scripts upload products successfully with 5 products then why not 50? and what's the TypeError about it? overall how to fix/improve this?
In your seed file you defined colors
as an array of 5 elements
and when generating the color for a product you are using the index of the current array value
name: `${COLORS[i].slice(0, 1).toUpperCase() + COLORS[i].slice(1)} shirt ${i}`
so when it get to the 6th iteration, COLORS[i]
becomes undefined
, hence the error TypeError: Cannot read properties of undefined (reading 'slice')
To fix this, replace that line with
name: `${COLORS[i % colors.length].slice(0, 1).toUpperCase() + COLORS[i % colors.length].slice(1)} shirt ${i}`