Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QraphQL response from useLoaderData is always undefined on first render #2489

Open
jeffspurlock opened this issue Sep 1, 2024 · 2 comments

Comments

@jeffspurlock
Copy link

What is the location of your example repository?

local

Which package or tool is having this issue?

Hydrogen

What version of that package or tool are you using?

2024.7.2

What version of Remix are you using?

2.10.1

Steps to Reproduce

If you modify the default HEADER_QUERY to include a request for two menus with aliases, like so

query Header(
    $country: CountryCode
    $collectionsMenuHandle: String!
    $siteMenuHandle: String!
    $language: LanguageCode
  ) @inContext(language: $language, country: $country) {
    shop {
      ...Shop
    }
    collectionsMenu: menu(handle: $collectionsMenuHandle) {
      ...Menu
    }
    siteMenu: menu(handle: $siteMenuHandle) {
      ...Menu
    }
    announcementBanners: metaobjects(type: "announcement_banner", reverse: true, first:10) {
    nodes {
      fields {
        key
        value
        type
      }
    }
  }

by default, this populates a header object in the loadCriticalData function. In the component of root.tsx, `const data = useRouteLoaderData<RootLoader<('root')' is called, and data is passed into the PageLayout component. In PageLayout, data is destructured in the props

export function PageLayout({
  cart,
  children = null,
  footer,
  header,
  isLoggedIn,
  publicStoreDomain,
}: PageLayoutProps) {...}

inside of which, header is passed into the

component. Note: so far the only thing that has changed from the default scaffolded hydrogen application is adding the second menu and aliases

Now inside

, i'm destructuring the header object in the props as

export function HeaderMenu({
  siteMenu,
  collectionsMenu,
  primaryDomainUrl,
  viewport,
  publicStoreDomain,
}: {
  siteMenu: HeaderProps['header']['siteMenu'];
  collectionsMenu: HeaderProps['header']['collectionsMenu'];
  primaryDomainUrl: HeaderProps['header']['shop']['primaryDomain']['url'];
  viewport: Viewport;
  publicStoreDomain: HeaderProps['publicStoreDomain'];
}) {...}

if i console.log(collectionsMenu), i can see all the data just fine, it has the shape of

{
  id: "gid://........",
 items: [ Array of menu item data ]
} 

but then if i console.log(collectionsMenu.items) it will say its undefined. You can even log them one right after another; collectionsMenu logs correctly with an items property, but collectionsMenu.items or collectionsMenu['items'] logs undefined.

Expected Behavior

I expect to be able to access the properties of the object returned by an asyncronous loader function that is set to await the result before returning it.

Actual Behavior

I cannot useLoaderData to build out my menu structures defined in shopify to populate the menu component on the site.

@jeffspurlock
Copy link
Author

So interestingly, if instead of passing collectionsMenu into the header component, if i just instantiate a new data=useLoaderData() inside the component, and access that it works. When its passed as a prop, it stays undefined until second render.

@scottdixon
Copy link
Contributor

Hey @jeffspurlock,

Thanks for the report! Sounds super strange 🤔 I'm unable to replicate, any chance you could provide a demo repo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants