简体   繁体   中英

proper use of onCompleted for GraphQL mutations

I want to run the query first. The query returns an id which is then required for the mutation. Currently, there's an issue with the order of how both things run from the handleSubmit() . If the mutation is successful, the console should print console.log('Checking'); but that does not happen. The only output I get on the console is What's the Id and the value is probably something that was stored in one of my previous attempts. If the id was derived from this particular round of query, I would have seen Working on the log, but that doesn't happen either.

 const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery, {
    variables: {
      where: { email: friendEmail.toLocaleLowerCase() },
    },
    onCompleted: () => getFriendId(),
  });



  const [
    createUserRelationMutation,
    {
      data: addingFriendData,
      loading: addingFriendLoading,
      error: addingFriendError,
    },
  ] = useCreateUserRelationMutation({
    variables: {
      input: {
        relatedUserId: Number(id),
        type: RelationType.Friend,
        userId: 5,
      },
    },
    onCompleted: () => addFriend(),
  });
  const getFriendId = () => {
    console.log('Working');
    if (data) {
      console.log(data);
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
      }
    } else {
      if (error) {
        setErrorMessage(error.message);
      }
    }
  };

  const addFriend = () => {
    console.log('Whats the Id', Number(id));
    if (addingFriendData) {
      console.log('Checking');
      console.log(addingFriendData);
    }
    if (addingFriendError) {
      console.log('errorFriend', addingFriendError.message);
      setErrorMessage(addingFriendError.message);
    }
  };

 const handleSubmit = () => {
    loadUsers();
    createUserRelationMutation();
  };

Before this, I was trying this:

const [id, setId] = useState('');
const [friendEmail, setFriendEmail] = useState('');

const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [createUserRelationMutation, { data: addingFriendData, loading: addingFriendLoading, error: addingFriendError }] = useCreateUserRelationMutation();

const getFriendId = () => {
    console.log('Email', friendEmail.toLocaleLowerCase());
    loadUsers({
      variables: {
        where: { email: friendEmail.toLocaleLowerCase() },
      },
    });
    if (data) {     
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);      
    } 
    addFriend();
  };

  const addFriend = () => {
    console.log('Whats the Id', Number(id));
       createUserRelationMutation({
        variables: {
               input: {relatedUserId: Number(id), type: RelationType.Friend, userId: 7 }
            },
       });
       if (addingFriendData){
         console.log('Checking')
         console.log(data);
       }
       if(addingFriendError){
         console.log('errorFriend', addingFriendError.message);
         setErrorMessage(addingFriendError.message);
       }
  }


const handleSubmit = () =>
    {getFriendId();};

However, in this case, the values of the id & other states weren't being updated timely. I was running a graphql query inside getFriendId() that returns an id, followed by a mutation (inside addFriend() , which uses the id, along with an input (email) that the user types in. The problem is that on the first attempt, the mutation works fine and with correct values. However, when I change the email address on the input and run the query/mutation again, the values from my previous attempt are being used.

In the second attempt, the mutation was still using the id that we got in the first attempt.

Edit:

onCompleted: (data) => getFriendId(data),

 const getFriendId = (data: any) => {
    console.log('Working');
    if (data) {
      console.log(data);
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
      }

Updated Code:

 const [friendEmail, setFriendEmail] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);

  const [
    createUserRelationMutation,
    {
      data: addingFriendData,
      loading: addingFriendLoading,
      error: addingFriendError,
    },
  ] = useCreateUserRelationMutation();


 const getFriendId = () => {
    console.log('Email', friendEmail.toLocaleLowerCase());
    loadUsers({
      variables: {
        where: { email: friendEmail.toLocaleLowerCase() },
      },
    });
    if (data) {
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
        addFriend(data.users.nodes[0].id); 

      }
    } else {
      console.log('No data');
      if (error) {
        setErrorMessage(error.message);
      }
    }
    //addFriend();
  };

  const addFriend = (idd: any) => {
    console.log('Whats the Id', Number(idd));
       createUserRelationMutation({
        variables: {
               input: {relatedUserId: Number(idd), type: RelationType.Friend, userId: 9 }
            },
       });
       if (addingFriendData){
         console.log('Checking')
         console.log(data);
       }
       if(addingFriendError){
         console.log('errorFriend', addingFriendError.message);
         setErrorMessage(addingFriendError.message);
       }
  }

    const handleSubmit = () =>
    {
    getFriendId();
    };

You don't need state to store ID, instead pass the Id to addFriend method like show below

    const [friendEmail, setFriendEmail] = useState('');
    const [errorMessage, setErrorMessage] = useState('');

    const _onLoadUserError = React.useCallback((error: ApolloError) => {
        setErrorMessage(error.message);
    }, []);

    const [
        createUserRelationMutation,
        {
            data: addingFriendData,
            loading: addingFriendLoading,
            error: addingFriendError,
            called: isMutationCalled
        },
    ] = useCreateUserRelationMutation();

    const addFriend = React.useCallback((idd: Number) => {
        console.log('Whats the Id', idd);
        createUserRelationMutation({
            variables: {
                input: { relatedUserId: idd, type: RelationType.Friend, userId: 9 }
            }
        });
    }, [createUserRelationMutation]);

    const getFriendId = React.useCallback((data: any) => {
        console.log('Email', friendEmail.toLocaleLowerCase());
        if (data) {
            if (data.users.nodes.length == 0) {
                console.log('No user');
                setErrorMessage('User Not Found');
            } else {
                console.log('ID', data.users.nodes[0].id);
                addFriend(Number(data.users.nodes[0].id));

            }
        }
    }, [friendEmail, addFriend]);

    const [loadUsers] = useLazyQuery(LoadUsersQuery, {
        onCompleted: getFriendId,
        onError: _onLoadUserError
    });

    const handleSubmit = React.useCallback(() => {
        loadUsers({
            variables: {
                where: { email: friendEmail.toLocaleLowerCase() },
            }
        });
    }, [loadUsers, friendEmail]);

    if (!addingFriendLoading && isMutationCalled) {
        if (addingFriendData) {
            console.log('Checking')
            console.log(data);
        }
        if (addingFriendError) {
            console.log('errorFriend', addingFriendError.message);
            setErrorMessage(addingFriendError.message);
        }
    }

Update

I have updated the above code, please refer to it. I'm assuming useCreateUserRelationMutation does not accept options as argument, if it accepts option then you could use onCompleted and onError just like loadUsers query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM