Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Show 'tracks' in 'genre' collection

default discord avatar
modgy.2 years ago
14

I have a collection called genres, and each item in that collection contains a genre, ie Hip-Hop, House, Punk, etc.



I have another collection called tracks, and in that I have a reference to the genres collection with

hasMany: true

so you can add a list of genres to a track.



On the frontend, I want to be able to click on a genre and see a list of tracks that contain that genre. For example, I click "Punk" and I can see "Ever fallen in love", "God save the queen", etc, from my tracks collection.



I'd thought this would be easy enough to do via GraphQL but I can't figure out how. My other idea would be to have a field in the genre that automatically pulls through the tracks as a field that I can more easily query with GraphQL but again I can't figure out how.



Any suggestions on querying data like this?

  • default discord avatar
    notchr2 years ago

    Hmm, I think I'd know how to do this with REST, but not graphql, what's your current query like?

  • default discord avatar
    modgy.2 years ago

    I've gotten as far as this

    @1049775120559898725



    query ListPicksTest {
      ListPicks(where: { genres: { exists: true }  }, limit: 300) {
        docs {
          genres {
            title
            slug
          }
        }
      }
    }


    I called ListPicks 'tracks' in my question just for clarity, but they're called List Picks here



    I'm not married to using GraphQL, I'm new to Payload coming from Sanity/Groq

  • default discord avatar
    notchr2 years ago

    And how do you issue that query?



    I'm not super familiar with graphql



    I usually do a fetch request

  • default discord avatar
    modgy.2 years ago

    I'm just in the graphql playground that payload supply at the moment

  • default discord avatar
    notchr2 years ago

    Hmm



    And that query doesnt return any results?

  • default discord avatar
    modgy.2 years ago

    I should say; I'm basing my approach to this on the Payload 'website' repo and they fetch docs like this:

    https://github.com/payloadcms/payload/blob/main/templates/website/src/app/_api/fetchDocs.ts

    So line 48:

    query: queryMap[collection].query,

    it fetches the doc based on the requested collection, and the query within that comes from GraphQL

  • default discord avatar
    notchr2 years ago

    But it doesn't return any results?

  • default discord avatar
    modgy.2 years ago

    So that query above does return results, it fetches all of the genres



    So it's sort of saying, "fetch the query if genres exists", which it does. But what I want it to say is "fetch the query if the genre equals 'punk'"

  • default discord avatar
    notchr2 years ago
    https://localhost:3000/api/listpicks?where[genre][equals]=rock

    would be the rest url with a fetch



    i think



    That says, get all list picks where the genre = rock

  • default discord avatar
    modgy.2 years ago

    Like:



    query ListPicksTest {
      ListPicks(where: { genres: { slug: { equals: "punk" } }  }, limit: 300) {
        docs {
          track
          genres {
            title
            slug
          }
        }
      }
    }


    Hmm so it should be possible with GraphlQL if it's possible with REST

  • default discord avatar
    notchr2 years ago

    Yep!



    Ill help out more soon, i gotta grab lunch

  • default discord avatar
    modgy.2 years ago

    No problemo



    I wonder if it's because 'genres' is a relationship with

    hasMany

    so a track could be tagged with 'punk', 'rock', etc



    the data looks like this



    "genres": [
      {
        "id": "65e1cca0575bfdb1bacdba33",
        "title": "Indie",
        "createdAt": "2024-03-01T12:40:00.655Z",
        "updatedAt": "2024-03-01T16:46:01.998Z",
        "slug": "indie"
      },
      {
        "id": "65e1ccab575bfdb1bacdba3b",
        "title": "Electronic",
        "createdAt": "2024-03-01T12:40:11.623Z",
        "updatedAt": "2024-03-01T16:45:56.866Z",
        "slug": "electronic"
      }
    ],


    This works actually:

    http://localhost:3000/api/list-picks?where[genres.slug][equals]=punk

    That seems to return what I'd expect. Question is how to do that in GraphQL, or should I just forego GraphQL altogether and just use REST 🤔

  • default discord avatar
    notchr2 years ago

    Well



    I'm a fan of REST, but it depends on what you're most comfortable with!

  • default discord avatar
    modgy.2 years ago

    I'd prefer REST I think, just unsure how to set this up with Payload. Typically when using Sanity I'd have a function like this:



    export function sanityFetch({ query, params = DEFAULT_PARAMS, tags = DEFAULT_TAGS }) {
      const isDraftMode = draftMode().isEnabled;
      if (isDraftMode && !token) {
        throw new Error("The `SANITY_API_READ_TOKEN` environment variable is required");
      }
    
      // @TODO this won't be necessary after https://github.com/sanity-io/client/pull/299 lands
      const sanityClient =
        client.config().useCdn && isDraftMode ? client.withConfig({ useCdn: false }) : client;
    
      return sanityClient.fetch(query, params, {
        // Only validate cache if there's a revalidation webhook setup
        cache: "no-store",
        ...(isDraftMode && {
          cache: undefined,
          token,
          perspective: "previewDrafts",
        }),
        next: {
          ...(isDraftMode && { revalidate: 30 }),
          tags,
        },
      });
    }


    and then could run

    sanityFetch.fetch(query, params, tags);

    I think I can probably close this as I seem to be able to do what I want using the REST API which I'll be using instead of GraphQL.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.