Passing Object Array to Client Side Component
Answered
Horned oak gall posted this in #help-forum
Horned oak gallOP
Currently I am grabbing an array of listings using an async function and want to pass this to a client component to map. The issue being I cannot .map() the dataArray into the client component nor is it allowing me to keep my client component as a client component if I just map the dataArray straight into the client component.
(some code redacted to keep the post smaller)
(server component)
(client component)
I have use client , and the useState commented out currently
(some code redacted to keep the post smaller)
(server component)
export default async function Listings({ searchParams }) {
const listingsData: Promise<Listing[]> = getAllListingsForEvent(event.eventId);
return (
<section className="">
<div>
<ul className="grid xl:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 grid-cols-1 gap-10 my-10 px-10 w-full flex flex-wrap justify-center">
<SwapListing promise={listingsData}/>
</ul>
</div>
</section>
)
}(client component)
export default async function SwapListing({ promise }: Props) {
const listings = await promise;
console.log(listings)
const content = listings.map(listing => {
// const [counter, setCounter] = useState(0);
const imagesLength = listing.images.length;
// const nextImage = () => {
// if (counter + 1 > imagesLength - 1) {
// setCounter(0);
// } else {
// setCounter(counter + 1);
// }
// };
//
// const backImage = () => {
// if (counter - 1 < 0) {
// setCounter(imagesLength - 1)
// } else {
// setCounter(counter - 1);
// }
// };
return (
<div className="flex flex-row justify-center">
{/*<button className="px-3 mt-48 rounded-3xl max-h-10 text-4xl flex-none hover:bg-rtOrange" onClick={nextImage}>*/}
{/* <*/}
{/*</button>*/}
<div className="flex flex-col rounded-xl border border-rtBlack border-2 max-w-md flex-grow hover:opacity-80">
<Link href={`/swaps/${listing.event.eventId}/listings/${listing.listingId}`}>
<div className="px-4 py-2 text-2xl truncate bg-rtBlue font-black rounded-t-lg">{listing.listingTitle}</div>
<div className="flex flex-col">
<div className="relative h-80 max-w-md">
<Image
src={listing.images[0]}
className="object-cover"
quality={80}
fill
alt="Frag Swap listing image"
/>
</div>
</div>
<div className="flex flex-row justify-between px-4 py-2">
<p>Price:</p>
<p>$ {listing.price}</p>
</div>
<div className="flex flex-row justify-between px-4 py-2">
<p>Available:</p>
<p>{listing.quantity}</p>
</div>
<div className="flex flex-row justify-between px-4 py-2">
{/*<p>Seller:</p>*/}
{/*<p>{identityName}</p>*/}
</div>
</Link>
</div>
{/*<button className="px-3 mt-48 rounded-3xl max-h-10 text-4xl flex-none hover:bg-rtOrange" onClick={backImage}>*/}
{/* >*/}
{/*</button>*/}
</div>
)
})
return content;
}I have use client , and the useState commented out currently
Answered by Plague
Wait I'm confused, you're using
You have to either:
1. resolve the promise in the server component by awaiting it
2. read the value of the promise using the [
async/await in the client component section? That's not supported. You have to either:
1. resolve the promise in the server component by awaiting it
2. read the value of the promise using the [
use](https://react.dev/reference/react/use) API in the client component (caveats may apply so please read the documentation)7 Replies
Wait I'm confused, you're using
You have to either:
1. resolve the promise in the server component by awaiting it
2. read the value of the promise using the [
async/await in the client component section? That's not supported. You have to either:
1. resolve the promise in the server component by awaiting it
2. read the value of the promise using the [
use](https://react.dev/reference/react/use) API in the client component (caveats may apply so please read the documentation)Answer
@Plague Wait I'm confused, you're using `async/await` in the client component section? That's not supported.
You have to either:
1. resolve the promise in the server component by awaiting it
2. read the value of the promise using the [`use`](https://react.dev/reference/react/use) API in the client component (caveats may apply so please read the documentation)
Horned oak gallOP
The async/await is in the server component(first code block), which then I pass into <SwapListing />
Sounds like I may just need to add await right before “getAllListingsForEvent”? On mobile but will try this tomorrow
@Horned oak gall The async/await is in the server component(first code block), which then I pass into <SwapListing />
directly under "(client component)" you have this code:
export default async function SwapListing({ promise }: Props) {
const listings = await promise;you cannot do that in a client component, in the server component code block you showed, you use the
async keyword but you don't await anything, you just initialize the promise@Plague you cannot do that in a client component, in the server component code block you showed, you use the `async` keyword but you don't await anything, you just initialize the promise
Horned oak gallOP
ahhh I should of removed those before posting my bad... They weren't there originally but I had them there to test other features for a bit.
Horned oak gallOP
Anyways here is the up to date working version now
export default async function Listings({ searchParams }) {
let event: Event = JSON.parse(searchParams.event);
console.log(event.eventId)
const listingsData: Promise<Listing[]> = await getAllListingsForEvent(event.eventId);
return (
<section className="">
<div>
<ul className="grid xl:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 grid-cols-1 gap-10 my-10 px-10 w-full flex flex-wrap justify-center">
{(await listingsData).map((listing) => (
<SwapListing listing={listing} key={listing.listingId}/>
))}
</ul>
</div>
</section>
)
}"use client"
import Image from "next/image";
import Link from "next/link";
import React, { useState } from "react";
export default function SwapListing({ listing }) {
const [counter, setCounter] = useState(0);
const imagesLength = listing.images.length;
const nextImage = () => {
if (counter + 1 > imagesLength - 1) {
setCounter(0);
} else {
setCounter(counter + 1);
}
};
const backImage = () => {
if (counter - 1 < 0) {
setCounter(imagesLength - 1)
} else {
setCounter(counter - 1);
}
};
return (
<div className="flex flex-row justify-center">
<button className="px-3 mt-48 rounded-3xl max-h-10 text-4xl flex-none hover:bg-rtOrange" onClick={nextImage}>
<
</button>
<div className="flex flex-col rounded-xl border border-rtBlack border-2 max-w-md flex-grow hover:opacity-80">
<Link href={`/swaps/${listing.event.eventId}/listings/${listing.listingId}`}>
<div className="px-4 py-2 text-2xl truncate bg-rtBlue font-black rounded-t-lg">{listing.listingTitle}</div>
<div className="flex flex-col">
<div className="relative h-80 max-w-md">
<Image
src={listing.images[counter]}
className="object-cover"
quality={80}
fill
alt="Frag Swap listing image"
/>
</div>
</div>
<div className="flex flex-row justify-between px-4 py-2">
<p>Price:</p>
<p>$ {listing.price}</p>
</div>
<div className="flex flex-row justify-between px-4 py-2">
<p>Available:</p>
<p>{listing.quantity}</p>
</div>
<div className="flex flex-row justify-between px-4 py-2">
{/*<p>Seller:</p>*/}
{/*<p>{identityName}</p>*/}
</div>
</Link>
</div>
<button className="px-3 mt-48 rounded-3xl max-h-10 text-4xl flex-none hover:bg-rtOrange" onClick={backImage}>
>
</button>
</div>
)
}