How to fix the error with InMemoryCache so as not to lose the results of previous queries in GraphQL?

  • 0
    In a React application, I made infinite scrolling, requesting data from a GraphQL query. But I incorrectly implemented caching of previous loaded results, as a result of which, when scrolling, new results are not added to the previously loaded ones, but replace them.
    I use Apollo, I did it according to their documentation, but I can't figure it out with InMemoryCache.

    This is what the query looks like:
    export const getEmailsQuery = gql`
      query GetEmails($offset: Int, $limit: Int) {
        getEmailAccounts(userInput: { offset: $offset, limit: $limit }) {
          id
          userId
          email
          dateCreated
          dateUpdated
        }
      }
    `;


    const [offset, setOffset] = useState(0);   // прибавляю offset после каждой прокрутки до конца экрана
    
      const {
        data: emailsData,
        loading: emailsDataLoading,
        fetchMore: emailsFetchMore,
        refetch: emailsRefetch,
      } = useQuery(getEmailsQuery, {
        variables: {
          offset,
          limit: 20,
        },
      });
     
      const cache = new InMemoryCache({
        typePolicies: {
          GetEmails: {
            fields: {
              getEmailAccounts: {
                keyArgs: [],
                merge(existing, incoming, { args: { offset }}) {
                  const merged = existing ? existing.slice(0) : [];
                  for (let i = 0; i < incoming.length; ++i) {
                    merged[offset + i] = incoming[i];
                  }
                  return merged;
              }
            }
          }
        }
      }});
    
        const handleScroll = async () => {
          if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return;
          await emailsFetchMore({
            variables: {
              offset
            },
            updateQuery: (prev, { fetchMoreResult }) => {
              if (!fetchMoreResult) return prev;
              return Object.assign({}, prev, {
                feed: [...prev.feed, ...fetchMoreResult.feed]
              });
            }
          });
          setOffset(offset + 20);
        };
    
        useEffect(() => {
          window.addEventListener("scroll", handleScroll);
          return () => window.removeEventListener("scroll", handleScroll);
        }, []);


    Displaying results
    {emailsData &&
              emailsData.getEmailAccounts.map((e, i) => (
    ...
              ))}


    If I do console.log (cache), then I don't find any data in it.

    Tell me where I went wrong.
    React Anonymous, Jun 29, 2020

  • 0 Answers
Your Answer
To place the code, please use CodePen or similar tool. Thanks you!