2

I am having a problem where my Administrator page is rendering without checking whether the current user has permission to view that page. Once it checks permissions (takes a second or so) and realises a user doesn't have permissions an error page occurs. I would ideally not like it to render at all until it checks permissions. I think the problem is that the query to get the current user's data is asynchronous and so I believe I need to use async and await to make it synchronous.

This is a AdministratorPage.jsx file that shouldn't render whilst permissions are checked

import currentUser from '../lib/currentUser';
import React, { Component } from 'react';
import { ApolloConsumer } from 'react-apollo';

class AdministratorPage extends Component {

    render() {
        return (
            <ApolloConsumer>
                {(client) => {
                currentUser(client).then((data) => {
                    if(!data.currentUser..permissions)) {
                        this.props.history.push('/error');
                    }
                    return (
                       ... content rendered ...

The execution of code calls the second return function before it completes the currentUser(client).then((data) => call but I would like this call to be completed first.

This is the currentUser.js file that executes the query to check the current user's data

import gql from 'graphql-tag';

export default apolloClient => apolloClient
    .query({
        query: gql`
            query CURRENT_USER {
                name
                age
                gender
                permissions
            }
        `,
    })
    .then(({ data }) => ({ currentUser: data }))
    .catch(() =>
        ({ currentUser: {} }));

I think I need to transform the query from currentUser.js into a synchronous function using async and await. Does anyone know how to do this?

Liv Stan
  • 409
  • 2
  • 6
  • 15
  • 1
    The usual way to deal with these kinds of issues is to either supply the user data from the backend directly or mask the page while it's loading. Although, if a user is logged in, you shouldn't really have any sort of wait time to retrieve their user data - they should have a session with that for fast access. – VLAZ Jun 27 '19 at 11:29
  • https://www.apollographql.com/docs/react/api/react-hooks/#uselazyquery – AlainIb Jun 22 '20 at 11:58
  • you can use useLazyQuery to run the query when you want, it's not async await but can be fired on need – AlainIb Jun 22 '20 at 11:58
  • Who marked this as a duplicate? An ajax call is not the same as using apolloclient which uses React hooks. – John Kim Dec 16 '22 at 01:09

2 Answers2

7

You can take advantage of async/await

import gql from 'graphql-tag';

const request = apolloClient => apolloClient
    .query({
        query: gql`
            query CURRENT_USER {
                name
                age
                gender
                permissions
            }
        `,
    })

async getUser = () => {
   const response = await request(apolloclient);
   console.log(await response);
}
Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
-3

In JavaScript synchronous request you can did only with XMLHttpRequest which opened with async flag equal false

let async = false 

XMLHttpRequest.open(method, url, async) // it's synchronous request.

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open

P.S in Apollo GraphQl you can't do it this.

Vadim Hulevich
  • 1,803
  • 8
  • 17
  • 1
    *”Synchronous requests on the main thread can be easily disruptive to the user experience and should be avoided; in fact, many browsers have deprecated synchronous XHR support on the main thread entirely”*. This is not a good advice. – Lennholm Jun 27 '19 at 11:38
  • @Lennholm Synchronous requests are permitted in Workers. – Vadim Hulevich Jun 27 '19 at 11:40
  • 1
    Workers are most certainly not relevant in this case – Lennholm Jun 27 '19 at 15:07
  • If you can't do it in Apollo GraphQL then this isn't a very useful answer to a question about how to do it in Apollo GraphQL. – JJJ Jun 27 '19 at 16:07
  • This is what i thought. And you can use xml http requests to query a graphql endpoint. you just have to build the query your self you cant use the apollo gql tags – James Harrington Jan 01 '21 at 22:09