Trouble targeting second array layer in React component

12 replies
Last updated: Jul 5, 2022
Hi all,I'm having trouble targeting the second array layer : This is what I have at the moment

const Home = ({ product, collection }) => {
  return (
    <>
      <Collection collection={collection} />
      {(collection ?? []).map((collection) => (
        <div key={collection.title}>
          {console.log(collection.products)}</div>
      ))}
    </>
  );
};
Now I can do

{console.log(collection.products)}
this shows me the products inside the collection but my goal is to fetch the title of the products in the collection so one would say it should be like this

{console.log(collection.products.title)}
but this wont work as it returns undefined. I have a feeling there needs a second mapping for this?

This is the data I want to target
Jul 4, 2022, 7:11 AM
This is beside Sanity, but you need to loop through the array of products to get each products title value.
e.g


collection.products.map(product => product.title) // Will return a list of every title for each product
Jul 4, 2022, 8:19 AM
If you change your examle to
collection.products[0].title
then you will get the title for the first product
Jul 4, 2022, 8:20 AM
Hi Sindre,I know it is outside of sanity but I'm having a hard time to find answers to my questions otherwise. I'm a self learning developer thats why I try to have good input from the people here.

So thank you for interacting with me and helping me throught this.

How would this code you suggest work in this case?

collection.products.map(product => product.title)
I have tried this before

collection.products[0].title
when you try to hit title it breaks
Jul 4, 2022, 8:28 AM
Hi Sadiki,Donโ€™t worry, we all started at some point
๐Ÿ™‚Regarding your question, you need to map over your products and extract the titles that way.
But I would recommend setting meaningful variable names in your code, so your code can be understood more readily (by yourself and others).
Example:

const allProducts = collection.products || [];
const productTitles = allProducts.map(product => product.title);
when it comes to mapping to get the titles, you could do that inside of your
<Collection/>
Component, if you are displaying the data you stored in there.If you want to display it within your code here, I would recommend going about it like this:


const Home = ({ product, collection }) => {
  return (
    <>
      <Collection collection={collection} />
      {(collection ?? []).map((collectionItem) => (
        <div key={collectionItem.title}>
          {const allProducts=collection.products || [];
            allProducts.map(product => (
            <p key={product._id}>{product.title}</p>
           }
          
           </div>
      ))}
    </>
  );
};
Hope that will help you with your question
๐Ÿ™‚
Jul 4, 2022, 8:57 AM
Thank you Saskia,I'm using the component to build the outcome. Let me show you what works and what dont at this point.

In my index i have a simple component like this

<Collection collectiondata={collectiondata} />
now inside that component i have this

{console.log(collectiondata[0].products[0].title)}
this logs the title of the first product in the first collection. this works fine.
Now I want to wrap it in a map so I can display all product titles that are inside the collections.

{(collectiondata ?? []).map((collectiondata) => (
      <div>
        {console.log(collectiondata.products.title)}
      </div>
    ))}
this dosnt work , I can also say I just want all the products inside the first collection like this

{console.log(collectiondata[0].products.title)}
this also dosnt work it looks very simple but somehow Im having trouble picking that data
Jul 4, 2022, 9:13 AM
Have you tried my map function from my previous answer?
      {(collection ?? []).map((collectionItem) => (
        <div key={collectionItem.title}>
          {const allProducts=collection.products || [];
            allProducts.map(product => (
            <p key={product._id}>{product.title}</p>
           }
          
           </div>
      ))}

Jul 4, 2022, 12:22 PM
But I would split the 2 map functions: the
collectiondata
in
home
and the
allProducts
in
collection
Jul 4, 2022, 12:23 PM
I found the problem to this. I had 2 empty collections that causes the problem. When I removed the 2 empty collections entirely it solved the errors and projected it as it should. Your method works but that seperates the products from the collection so it makes it harder to link the products to a collection. My idea was to have it all dynamicly so if there is a change somehwere or something has been added it will all dynamicly change. Thanks for looking at my code and helping me out I really appreciate it !
Jul 4, 2022, 1:21 PM
Wonderful you found it.If I may, maybe it would be good to setup a validation in your collection array, so it will throw a warning and keeps editors from publishing
๐Ÿ™‚With the dynamic rendering, this still would be the case if you map your second array in the component, but it also makes your code more manageable long term.
Jul 4, 2022, 1:27 PM
Do you have a example for how to set up the warning properly?
Jul 4, 2022, 1:34 PM
Sure!As described
here , the field (array) in your Sanity Studio should look something like this:

{
  title: 'Title',
  name: 'array',
  type: 'array',
  validation: Rule => Rule.max(50).warning('Shorter lists are usually better'),
...}
Jul 5, 2022, 11:18 AM
Thank you Saskia !
Jul 5, 2022, 12:01 PM

Sanityโ€“ build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?