#Content collections: GetEntries for all items in collection

1 messages · Page 1 of 1 (latest)

sweet token
#

I have a page where I want to list all content from one collection and all data that each item references from another collection. I am having trouble working with collection references within a loop.

I have the two following schemas:

const peopleCollection = defineCollection({
  type: "content",
  schema: z.object({
    name: z.string(),
    avatar: z.string(),
  })
});
const projectCollection = defineCollection({
  type: "content",
  schema: z.object({
    title: z.string(),
    teamMembers: z.array(reference("people")),
  })
});

On my index.astro page, I want to list all projects, displaying their titles and associated team member names.

// Set in my frontmatter
const projects = await getCollection("projects");

// In the markup
<div>
  { projects.map((project) => (
    <article>
      <p>{ project.data.title }</p>
      <!-- How can I make the following work? -->
      { project.data.teamMembers.map((person) => (
        <p>{ person.data.name }</p>
      ))}
    </article>
  ))}
</div>
lean breachBOT
#

Hi @sweet token. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To display the associated team member names for each project, you need to use the getEntries() function to retrieve the referenced entries from the teamMembers array. This function retrieves multiple collection entries from the same collection, which is useful for returning an array of referenced entries to access their associated data.

Here's how you can modify your code to achieve this:

---
import { getCollection, getEntries } from 'astro:content';
const projects = await getCollection('projects');
for (const project of projects) {
  project.data.teamMembers = await getEntries(project.data.teamMembers);
}
---
<div>
  { projects.map((project) => (
    <article>
      <p>{ project.data.title }</p>
      { project.data.teamMembers.map((person) => (
        <p>{ person.data.name }</p>
      ))}
    </article>
  ))}
</div>

In this code, we're looping over each project and replacing the teamMembers array with the actual entries from the 'people' collection. Now, when you map over project.data.teamMembers in your markup, person.data.name will correctly display the name of each team member.

Please note that this code assumes that your getCollection and getEntries functions are working correctly and that your schemas are correctly defined and exported.

For more information, you can refer to the Astro documentation on querying collections (https://docs.astro.build/en/guides/content-collections#querying-collections) and the Astro API reference for getEntries() (https://docs.astro.build/en/reference/api-reference#getentries).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@sweet token kapa.ai is still learning and improving, please let us know how it did by reacting below

sweet token
#

@lean breach This seems to work the first time the page loads, but returns undefined on the first refresh, then errors out with the next, stating: "Cannot read properties of undefined (reading 'collection')" - I'm assuming this is because we're overwriting the project.data.people value?

lean breachBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, you're correct. Overwriting project.data.teamMembers with the actual entries could be causing this issue. When you refresh the page, the original references in project.data.teamMembers are lost because they've been replaced with the actual entries. This could lead to undefined values and subsequent errors.

To avoid this, you can create a new array that combines the project data with the actual team member entries, instead of overwriting the original data. Here's how you can modify your code:

---
import { getCollection, getEntries } from 'astro:content';
const projects = await getCollection('projects');
const projectsWithTeamData = [];

for (const project of projects) {
  const teamMembers = await getEntries(project.data.teamMembers);
  projectsWithTeamData.push({ ...project, data: { ...project.data, teamMembers } });
}
---
<div>
  {{ projectsWithTeamData.map((project) => (
    <article>
      <p>{{ project.data.title }}</p>
      {{ project.data.teamMembers.map((person) => (
        <p>{{ person.data.name }}</p>
      ))}}
    </article>
  ))}}
</div>

In this code, we're creating a new array projectsWithTeamData and pushing each project into it with its team member entries. This way, we're not overwriting the original project.data.teamMembers values, which should prevent the error you're seeing.

#

Again, please ensure that your getCollection and getEntries functions are working correctly and that your schemas are correctly defined and exported. For more information, refer to the Astro documentation on querying collections (https://docs.astro.build/en/guides/content-collections#querying-collections) and the Astro API reference for getEntries() (https://docs.astro.build/en/reference/api-reference#getentries).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@sweet token kapa.ai is still learning and improving, please let us know how it did by reacting below

sweet token
#

@lean breach What is the best way to tag / notify an actual person to verify this response?

lean breachBOT
#

Let me check the knowledge base for you. One moment! :books:

#

As an AI, I don't have the ability to tag or notify a person directly. However, you can usually mention someone in a comment or post by using the "@" symbol followed by their username, depending on the platform you're using. For example, on GitHub, you could write @username to mention someone.

Please note that the effectiveness of this method depends on the platform's notification settings and whether the person you're trying to notify has enabled notifications.

If you're working within a team, it might be more effective to use a direct communication tool like email or a chat application to ask someone to verify the response.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@sweet token kapa.ai is still learning and improving, please let us know how it did by reacting below