Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Fetching nested metafield values with GraphQL & Hydrogen

Fetching nested metafield values with GraphQL & Hydrogen

LeanMassLabs
Shopify Partner
2 0 0

Our page has a lot of information packed into each product page.

It is not uncommon to have Metaobjects containing lists of other Metaobjects.

 

Fetching nested metafield values

What is the standard practice when it comes to fetching nested metafield values, specifially values with type

list.metaobject_reference

 

The fragment, as part of query

 

fragment ProductPageSections on Product {
...
    science: metafield(namespace: "custom", key: "study_section") {
      key
      reference {
        ... on Metaobject {
          fields {
            key
            value
            type
          }
        }
      }
    }
}

 

Which returns

 

"study_section": {
        "key": "study_section",
        "reference": {
          "fields": [
            ...
            {
              "key": "styled_list",
              "value": "[\"gid://shopify/Metaobject/26311262474\",\"gid://shopify/Metaobject/26312540426\",\"gid://shopify/Metaobject/26312212746\",\"gid://shopify/Metaobject/26312999178\",\"gid://shopify/Metaobject/26313130250\"]", <-- This is the data I need to access.
              "type": "list.metaobject_reference"
            },
            ...
          ]
        }
      },

 

 

I've been able to "brute force" this sort of request in the loader function, but I get the feeling that this is not how these queriesn are meant to be used.

 

Example of loader function in products.handle$.tsx

 

// products.$handle.tsx

export async function loader(args: LoaderFunctionArgs) {
  const deferredData = loadDeferredData(args);
  const criticalData = await loadCriticalData(args);

  const { summary, references, whatToExpect, science } = criticalData.product;


  const sections = await Promise.all(
    [summary, references, whatToExpect, science].map(async (section) => {
      if (!section?.reference?.fields) {
        return section;
      }

      const newFields = await Promise.all(
        section.reference.fields.map(async (field) => {
          if (!field.value) return field;

          if (field.type === 'list.metaobject_reference') {
            const formattedJson = JSON.parse(field.value) as string[];

            // Simple fetching query
            let valueFetched = await fetchMetaobjectData(
              formattedJson,
              args.context.storefront,
            );

            return { ...field, valueFetched };
          }
          return field;
        }),
      );

      return {
        ...section,
        reference: { fields: newFields },
      } as PageSection;
    }),
  );

  return defer({
    ...deferredData,
    ...criticalData,
    sections,
  });
}

 

 

This does return the values I expect.

 

However, given that the fetched sections (valueFetched ) can also contain lists of metaobjects - it quickly starts to become very complicated.

 

What is the standard practice on fetching nested metafields and objects like this?

 

Please have patience with my limited experience with Graphql ^^

Thank you.

Replies 0 (0)