i am trying to fetch data from sanity in nextjs but i keep getting this error Error: expected ']' following expression. I'm a novice in this, been on it, i don't even know the source of the error
these are my schemas for product.ts
import {defineField, defineType} from 'sanity'
export default defineType({
name: 'product',
title: 'product',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'slug',
title: 'Slug',
type: 'slug',
options: {
source: 'title',
maxLength: 96,
},
}),
defineField({
name: 'price',
title: 'Price',
type: 'number',
}),
defineField({
name: 'oldprice',
title: 'Old Price',
type: 'number',
}),
defineField({
name: 'mainImage',
title: 'Main image',
type: 'image',
options: {
hotspot: true,
},
fields: [
{
name: 'alt',
type: 'string',
title: 'Alternative Text',
}
]
}),
defineField({
name: 'categories',
title: 'Categories',
type: 'array',
of: [{type: 'reference', to: {type: 'category'}}],
}),
defineField({
name: 'stock',
title: 'Out Of Stock',
type: 'boolean',
}),
defineField({
name: 'display',
title: 'Display',
type: 'boolean',
}),
defineField({
name: 'created',
title: 'Created when',
type: 'datetime',
}),
defineField({
name: 'body',
title: 'Body',
type: 'blockContent',
}),
],
preview: {
select: {
title: 'title',
author: 'author.name',
media: 'mainImage',
},
prepare(selection) {
const {author} = selection
return {...selection, subtitle: author && `by ${author}`}
},
},
})
category.ts
import {defineField, defineType} from 'sanity'
export default defineType({
name: 'category',
title: 'Category',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'slug',
title: 'Slug',
type: 'slug',
options: {
source: 'title',
maxLength: 96,
},
}),
defineField({
name: 'mainImage',
title: 'Main image',
type: 'image',
options: {
hotspot: true,
},
fields: [
{
name: 'alt',
type: 'string',
title: 'Alternative Text',
}
]
}),
defineField({
name: 'description',
title: 'Description',
type: 'text',
}),
],
})
i used client and groq here
import { createClient, groq } from 'next-sanity'
import { apiVersion, dataset, projectId, useCdn } from '../env'
export async function getProducts(){
const client = createClient({
apiVersion,
dataset,
projectId,
useCdn,
})
return client.fetch(
groq`*[_type = "product"]{
_id,
name,
"slug":slug.current,
"mainImage": image.asset->url,
price,
oldprice,
category->{
name,
"id": _id,
"mainImage": image.asset->url
},
stock,
display,
created,
body,
}`
)
}
export async function getCategory(){
const client = createClient({
apiVersion,
dataset,
projectId,
useCdn,
})
return client.fetch(
groq`*[_type = "category"]{
_id,
name,
"slug":slug.current,
"mainImage": image.asset->url,
description,
}`,
)
}
this is my product page
export default async function Product () {
const cats = await getCategory()
return (
<><div className='ml-6 pl-6'>
<p className='font-normal leading-9 text-4xl font-sans ml-6 pl-6 pt-2 pb-6 mb-6'>Product</p>
</div><main className='mx-6 px-6 py-6 my-6'>
<div className="grid grid-cols-4 place-content-center ml-6 pl-6">
{cats.map((item: { _id: React.Key | null | undefined; mainImage: string | StaticImport; name: string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | React.PromiseLikeOfReactNode | null | undefined }) => (
<div className="w-10/12 bg-white" key={item._id}>
<a href="#">
<Image width={300} height={300} id='image' className="w-screen md:h-fit" src={item.mainImage} alt="product image" />
</a>
<div className="px-5 pb-5 py-3 text-center">
<Link href="#">
<h5 className="text-base font-sans leading-6 font-bold text-black">{item.name}</h5>
</Link>
<div className="mb-5">
<span className="text-xs font-semibold text-[#3a3a3a] leading-6 text-center">5 PRODUCTS</span>
</div>
</div>
</div>
))}
product/[category]/page.tsx
export default async function Product () {
const products: IItem[] = await getProducts()
return (
<><div className='ml-6 pl-6'>
<p className='font-normal leading-9 text-4xl font-sans ml-6 pl-6 pt-2 pb-6 mb-6'>Categories</p>
</div>
<main className="">
<div className="grid grid-cols-4 place-content-center ml-6 pl-6">
{products.map(item => (
<div className="w-10/12 bg-white" key={item.id}>
<a href="#">
<Image width={300} height={300} id='image' className="w-screen md:h-fit" src={item.mainImage} alt="product image" />
</a>
<div className="px-5 pb-5 py-3">
<Link href="#">
<p className="text-sm font-sans leading-6 font-normal text-[#3a3a3a]">{item.category}</p>
</Link>
<Link href="#">
<h5 className="text-base font-sans leading-6 font-bold text-black">{item.name}</h5>
</Link>
<div className="flex items-center mt-2.5 mb-5">
<span className="text-sm font-bold text-[#3a3a3a] leading-6">₦{item.price}</span>
</div>
<div className="flex items-center justify-between">
<a href="#" className="text-white bg-[#B1250A] hover:bg-black focus:ring-4 focus:outline-none focus:ring-black font-bold rounded-lg text-base px-5 py-2.5 text-center dark:bg-[#B1250A] dark:hover:bg-black dark:focus:ring-[#B1250A]">Add to cart</a>
</div>
</div>
</div>
))}
these are the interfaces
// Define a type for your item
export interface IItem {
_id: number;
name: string;
slug: string;
price: number;
oldprice: number;
mainImage: string;
category: string[];
stock: boolean;
display: boolean;
created: number;
body: string;
};
export interface ICategory {
_id: string;
name: string;
mainImage: string;
slug: string;
description: string;
}
please will glad if anyone could help me with this error. thanks
i tried checking if there are typos and corrected them still same error, looked online still couldn't find solution to it.
RESOLVED THE ISSUE
Well, i didn't really find the reason for the error but all I did was break down my codes, restructured them and voila, it worked
I recently came across this issue and I believe your issue is also query related. Instead of an assignment,
_type
should be checking for equality. In your case, instead of:It should be