Search code examples
javascriptreactjsgraphqlgithub-api

Struggling to use Github graphQL API


I was looking to get some help with putting some of my pinned repositories on my personal website using the GitHub graphQL API. I have set up my my query correctly I believe as when I console.log my data that was fetch I receive the following response in the terminal.

Response in terminal from query

but I've been running into issues later on in my code when I try use my renderPinnedItems functions to map the 3 pinned repositories.

This should be all relevant code.

import React, { useEffect, useState } from "react";
import {
  ApolloClient,
  InMemoryCache,
  createHttpLink,
  gql,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context";

import "./portfolio.css";
import { shouldCanonizeResults } from "@apollo/client/cache/inmemory/helpers";

export default function Portfolio() {
  
  const [data, setData] = useState({});

  const baseUrl = "https://api.github.com/graphql";

  const httpLink = createHttpLink({
    uri: baseUrl,
  });

  const firstHalf = "ghp_VxgRIC5d3umzSpu54U6";
  const secondHalf = "VUhW2ECwrov1SNUcK";

  const authLink = setContext((_, { headers }) => {
    return {
      headers: {
        ...headers,
        authorization: `Bearer ${firstHalf.concat(secondHalf)}`,
      },
    };
  });

  const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
  });

  useEffect(() => {
    client.query({
        query: gql`
          {
            user(login: "dessygil") {
              pinnedItems(first: 6) {
                edges {
                  node {
                    ... on Repository {
                      name
                      createdAt
                      description
                      repositoryTopics(last: 10) {
                        edges {
                          node {
                            topic {
                              name
                            }
                          }
                        }
                      }
                      stargazerCount
                      url
                    }
                  }
                }
              }
            }
          }
        `,
      })
      .then((response) => {
        console.log(response);
        setData(result.data.user.pinnedItems.edges.filter(({ node }) => node));
      });
  }, []);


  const renderPinnedItems = () => {
    data.map(({node}, i) => {
      
    });
  }

  return (
    <div className="portfolio">
      <h2 className="numbered-heading">Portfolio</h2>
      {(Object.keys(data).length === 0) ? <p> Loading </p> : renderPinnedItems()}
    </div>
  );
}

I Have tried

data.map(({node}, i) =\> {
    console.log(node.name)
});

and from this I received the correct information for the names of my repositories, but if I try

data.map(({node}, i) =\> {
    return (
        <p>{node.name}</p>
    );
});

it wont work. I'm confused why it wouldn't work. I don't know if its because it's not a proper javascript object when i receive my data from my query or I'm using a return statement in a map function. I've tried for days.


Solution

  • Given the data you're interested in is an array, you should initialise it as such. I'd also give it a more meaningful name

    const [pinnedItems, setPinnedItems] = useState([]);
    

    You can extract the node property from each edges entry using map()

    setPinnedItems(response.data.user.pinnedItems.edges.map(({ node }) => node));
    

    Now you just need to render it

    {
      pinnedItems.length ? (
        pinnedItems.map((node) => <p key={node.id}>{node.name}</p>)
      ) : (
        <p>Loading</p>
      );
    }