0

This is not the first time I've encountered this issue with GraphQL, where I will be able to clearly see that the correct data is being fetched by using console.log but it will render nothing in the UI. The last time I had this problem, the issue was that the "id" wasn't included for one of the nested objects. In this case, I've ensured that both exist:

topBattles { 
  id 
  battlers { 
    id
  }
}

If I recall, I was also able to detect that error by console.logging the error that gets returned by UseQuery. In this case, no error is being shown.

In graphiql, I can see that I'm receiving the correct data:

enter image description here

This is all of the code for the React front-end. There's nothing noteworthy, it's calling the same GraphQL query that worked in GraphiQl with the same arguments

function TopBattles() {
  const { loading, data, error } = useQuery(GET_TOP_BATTLES, {
    variables: { battleCount: 5, dateRange: "Weekly" },
  });

  React.useEffect(() => {
    console.log(data);
    console.log(error);
  }, [data]);

  if (loading) return "Loading...";
  return (
    <>
      {data?.topBattles?.length > 0
        ? data.topBattles.map((battle) => {
            <div>Foo</div>;
          })
        : "bar"}
    </>
  );
}

export default TopBattles;

from the console.log above, error returns undefined. Console.log.data returns the correct data: enter image description here

Yet for the code:

return (
    <>
      {data?.topBattles?.length > 0
        ? data.topBattles.map((battle) => {
            <div>Foo</div>;
          })
        : "bar"}
    </>
  );

Nothing at all is being rendered. The word "bar" is not even being rendered, which means that it's recognizing that there is an array of data and the data has a length. If I change the code to data?.topBattles?.length > 3 it will render "bar" because the array only has 2 elements in it.

1
  • You forgot the return. { return <div>... } Commented Aug 3, 2022 at 13:59

2 Answers 2

1

What you're missing is the explicit return statement in your arrow function [1]:

return (
    <>
      {data?.topBattles?.length > 0
        ? data.topBattles.map((battle) => {
            return <div>Foo</div>; // <== Should have an explicit return
          })
        : "bar"}
    </>
  );

// Implicit return (no {})
()=> <div>Foo</div>

// Explicit return (with {})
()=> { return <div>Foo</div> }

[1] Arrow Function Body

Sign up to request clarification or add additional context in comments.

2 Comments

hmm.. this did work, but I'm a little confused as to why. I've definitely used this method before and had no issues with it. I though the return on the outer scope would handle the return for the entire react fragment. I'm unsure why it wouldnt work in this context, but is currently working in others that seem identical
Update from Hasan's comment, I now see that what happened is I used curly braces in the map in this instance, and I did not use them in the instances where this method worked. Thanks all for your help
1

Like Kostas mentioned, you forgot the return statement, however if you're only rendering a single element, I would suggest doing it like:

return (
    <>
      {data?.topBattles?.length > 0
        ? data.topBattles.map
        (
         (battle) => 
            <div>Foo</div>
         )
        : "bar"}
    </>
  );

If you don't use the curly braces, you don't need return, this can be applied everywhere.

1 Comment

Thanks. I now see the issue is that I normally use this method, but in this particular instance I unwittingly added in curly braces, which required me to include a "return" and I wasn't aware of the difference until now

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.