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);
},
});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With