Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useLazyQuery not being called after onClick

I'm trying to check if my user isLoggedIn with a query from GraphQL API data from the user if it's loggedin if not it's supposed to return undefined or some error.

The question is I have a func called removeSession that deletes from my localStorage the token when users click in the logout button. The problem starts now, I've realized that my token was being cleared from localStorage but the userLAzyQuery wasn't get triggered after. So to inspect I started to delete de token manually and after the onClick I invoked the sendQuery()

To force my inspection I created onCompleted and onError callback after the query, and guess what? not being called either.

header.js

import { Fragment, useEffect } from 'react';
import Link from 'next/link';
import { isAuthenticatedQuery } from '../queries';
import { useQuery, useLazyQuery } from '@apollo/react-hooks';
import Router from 'next/router';

function isActive(pathname) {
  return typeof document !== 'undefined' && document.location.pathname === pathname;
}

const Header = () => {
  const { loading, data: dataAuth, error } = useQuery(isAuthenticatedQuery);

  const [sendQuery, { data: dataAuthLazy, error: errorsLazy }] = useLazyQuery(isAuthenticatedQuery, {
    onCompleted(data) {
      console.log('invoked onCompleted', data);
    },
    onError(err) {
      console.log('onerror', err);
    },
  });

  function removeSession() {
    localStorage.removeItem('token');
    sendQuery();
    console.log('inside removeSession');
    Router.push('/');
  }

  return (
    <nav>
      <div className="left">
        <Link href="/">
          <a data-active={isActive('/')}>Blog</a>
        </Link>
        <Link href="/drafts">
          <a data-active={isActive('/drafts')}>Drafts</a>
        </Link>
      </div>
      <div className="right">
        {!!dataAuth || !!dataAuthLazy ? (
          <Fragment>
            <Link href="/create">
              <a data-active={isActive('/create')}>+ Create draft</a>
            </Link>
            <Link href="/login" >
              <a onClick={() => sendQuery()}>Logout</a>
            </Link>
          </Fragment>
        ) : (
          <Fragment>
            <Link href="/signup">
              <a data-active={isActive('/signup')}>Signup</a>
            </Link>
            <Link href="/login">
              <a data-active={isActive('/login')}>Login</a>
            </Link>
          </Fragment>
        )}
      </div>
      <style jsx>{`
        nav {
          display: flex;
          padding: 2rem;
          align-items: center;
        }

        .bold {
          font-weight: bold;
        }

        a {
          text-decoration: none;
          color: gray;
          font-weight: regular;
          display: inline-block;
        }

        .left a[data-active='true'] {
          color: #000;
          font-weight: bold;
        }

        a + a {
          margin-left: 1rem;
        }

        .right {
          margin-left: auto;
        }

        .right a {
          padding: 0.5rem 1rem;
          border-radius: 5px;
          background: hsla(0, 89%, 63%, 0.79);
          color: white;
          font-weight: 500;
        }

        .right a:hover {
          background: hsl(0, 72%, 54%);
        }
      `}</style>
    </nav>
  );
};

export default Header;

queries/index.ts

export const isAuthenticatedQuery = gql`
  query isAuthenticatedQuery {
    me {
      id
      name
      email
    }
  }
`;

I'm using next.js, apollo 3, react16.12 FYI

In my network tabs no signal of some XHR activity

Update 1: I added fetchPolicy in my lazyQuery and my request appeared in chromedev tools but with status canceled

  const [sendQuery, { data: dataAuthLazy, error: errorsLazy }] = useLazyQuery(isAuthenticatedQuery, {
    fetchPolicy: 'no-cache',
    onCompleted(data) {
      console.log('invoked onCompleted', data);
      Router.push('/');
    },
    onError(err) {
      console.log('onerror', err);
    },
  });
like image 749
Yuri Ramos Avatar asked Dec 23 '22 18:12

Yuri Ramos


1 Answers

You're already running the same query when the component mounts here:

const { loading, data: dataAuth, error } = useQuery(isAuthenticatedQuery)

That means, by default, subsequent fetches of the same query will be fulfilled from the cache. This is why you don't see anything in the Network tab.

In order to force the request to be fulfilled by the server, we need to change the fetch policy to something like network-only:

const [sendQuery, { data: dataAuthLazy, error: errorsLazy }] = useLazyQuery(isAuthenticatedQuery, {
  fetchPolicy: 'network-only',
})

I would expect onCompleted to be executed regardless of how the query was fulfilled, but I can't speak to whether that is intended behavior or a bug.

like image 156
Daniel Rearden Avatar answered Jan 05 '23 18:01

Daniel Rearden