DEV Community

Cover image for Creating a Reddit Clone Using React and GraphQL - 08
Rasika Gayan Gunarathna
Rasika Gayan Gunarathna

Posted on • Edited on • Originally published at rasikag.com

Creating a Reddit Clone Using React and GraphQL - 08

From the last blog post, we saw that there is an issue while updating the name on the home page. To fix that we need to add update the cache mechanism. Let’s add the relevant packages for it.

yarn add @urql/exchange-graphcache
Enter fullscreen mode Exit fullscreen mode

Now we need to add the exchanges to createClient in _app.tsx page. Make sure that cacheExchange is coming from @urql/exchange-graphcache . Now we need to have custom update. To do that add the update property to cacheExchange ‘s options. Inside the Mutation Object it needs to match the names.

exchanges: [
  dedupExchange,
  cacheExchange({
    updates: {
      Mutation: {
        login: (result: LoginMutation, args, cache, info) => {
          cache.updateQuery({ query: MeDocument }, (data: MeQuery) => {});
        },
      },
    },
  }),
  fetchExchange,
];
Enter fullscreen mode Exit fullscreen mode

Here, type support is a bit lacking. So we are creating a helper function.

function cacheUpdateQuery<Result, Query>(
cache: Cache,
qi: QueryInput,
result: any,
fn: (r: Result, q: Query) => Query
) {
    return cache.updateQuery(qi, (data) => fn(result, data as any) as any);
}
Enter fullscreen mode Exit fullscreen mode

Now, instead of calling updateQuery inside the Mutation object we can use this function. We are adding cache update for every login and register. Once we replace the code, we will end up with the below code.


login: (_result, args, cache, info) => {
  cacheUpdateQuery<LoginMutation, MeQuery>(
    cache,
    { query: MeDocument },
    _result,
    (result, query) => {
      if (result.login.errors) {
        return query;
      } else {
        return {
          me: result.login.user,
        };
      }
    }
  );
},
register: (_result, args, cache, info) => {
  cacheUpdateQuery<RegisterMutation, MeQuery>(
    cache,
    { query: MeDocument },
    _result,
    (result, query) => {
      if (result.register.errors) {
        return query;
      } else {
        return {
          me: result.register.user,
        };
      }
    }
  );
}

Enter fullscreen mode Exit fullscreen mode

One thing we need to change here that we repeat that the user props all over the graphql queries. So we are moving it to fragment.

Now we are going to add the Logout function. To do that we need to add the logout mutation. In there we can use a request to destroy the session in the server and a response object to clear the cookie.

@Mutation(() => Boolean)
  logout(@Ctx() { req, res }: RedditDbContext) {
    return new Promise((resolver) =>
      req.session.destroy((err) => {
        res.clearCookie(COOKIE_NAME);
        if (err) {
          console.log(err);
          resolver(false);
          return;
        }
        resolver(true);
        // TODO: Seems I need to check this again
      })
    );
}

Enter fullscreen mode Exit fullscreen mode

Now we are coping the GraphQL query and generate the types form the web app.

Here is the logout query from GraphQL Playground.


mutation {
  logout
}

Enter fullscreen mode Exit fullscreen mode

Then add this in the NavBar logout button.


<Button
  onClick={() => {
    logout();
  }}
  isLoading={logoutFetching}
  variant="link"
>

Enter fullscreen mode Exit fullscreen mode

Up to now, we are able to successfully removed the cookie but still, the cache is not updated. So let’s add a new mutation to cacheExchange .


logout: (_result, args, cache, info) => {
cacheUpdateQuery<LogoutMutation, MeQuery>(
  cache,
  { query: MeDocument },
  _result,
  () => {
    return {
      me: null,
    };
  }
);
},

Enter fullscreen mode Exit fullscreen mode

Now once we log out, the cache also set to null .

I will wrap up this post from here. If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.
That’s for today friends. See you soon. Thank you.

References:

This article series based on the Ben Award - Fullstack React GraphQL TypeScript Tutorial. This is amazing tutorial and I highly recommend you to check that out.

Main image credit

Top comments (0)