Send Apollo GraphQL mutation request from React to Contentful - reactjs

I have a simple app built using React + contentful, I'm using apollo as a client.
I have a simple array of objects which I retrieve using query and which I'd like to update directly from UI.
this is my query
export const GET_RADIO = gql`
query getUrl {
allContentfulRadioUrl {
nodes {
url
radioName
}
}
}
`;
it works fine.
Then this is my mutation:
export const NEW_RADIO = gql`
mutation addNewRadio($url: String!, $name: String!) {
newRadio(url: $url, radioName: $name) {
allContentfulRadioUrl {
nodes {
url
radioName
}
}
}
}
`;
I'm passing the data to the mutation in this way:
const [addRadio] = useMutation(NEW_RADIO);
const submit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
addRadio({
variables: { url: formState.url, radioName: formState.radioName },
});
};
but I keep having errors in the response:
GraphQLError: Variable "$name" of required type "String!" was not provided."
It's my first time using GraohQL and this stack so I'm sure I'm missing something.
what do I did wrong?

I've just found out that the plugin gatsby-source-contentful is only for querying data and not for mutations, so i was trying to do something impossible

Related

Apollo Client React: how to pass the data obtained from a query as an argument in another query in graphql?

I am using Apollo client in React, I have two queries. At the first, it will return the phone value and the second uses the phone as a parameter. I want two queries run one by one and return value from two queries at the end of the pipe. I don't know Apollo client in react can do that or not?
export const GET_DETAIL = gql`
query GetDetail($id: uuid!) {
data: data_user_by_pk(id: $id) {
phone
}
}
`;
export const GET_DETAIL_BY_PHONE = gql`
query GetDetailByPhone($phone: String!) {
data: data_user_get_checked_in_companies_by_phone(input: { phone_number: $phone }) {
name
}
}
`;

Refetching a query using Apollo-Client throws an error

I am using Apollo-client to post a mutation to my graphql server. When the mutation is completed, I want to refetch that data. I tried using the refetchQueries argument in the useMutation hook, however I receive this error when I execute the code:
query option is required. You must specify your GraphQL document in
the query option.
This is the line of code that sends the mutation:
const [addUser, { data, loading, error }] =
useMutation(ADD_USER_QUERY, {
refetchQueries:[GET_USERS_QUERY]
});
This is my query (the hardcoded arguments were to see if the issues was due to passing variables):
export const ADD_USER_QUERY = gql`
mutation {
createUser(name: "Albert Einstein", email: "albert#yahoo.ca") {
id
name
}
}
`;
Thank you!
Alright so I figured out what the issue was. I had to pass an object with a "query" key in the refetchQueries array:
const [addUser, { data, loading, error }] =
useMutation(ADD_USER_QUERY, {
refetchQueries: [{ query: GET_USERS_QUERY }],
});
It's weird though because it isn't mentioned in the ApolloDocs. They simply use an array...
// Refetches two queries after mutation completes
const [addTodo, { data, loading, error }] = useMutation(ADD_TODO, {
refetchQueries: [
GET_POST, // DocumentNode object parsed with gql
'GetComments' // Query name
],
});
Does anyone know why that is?
Thanks!

to perform multiple dependent mutation - grandstack apollo graphql 3.3

I've a bit of confusion how to perform multiple mutation in graphql.
I've read articles about using of graphql() function or compose() function, but i haven't understood if these are the legacy way to do it (version 2)
or is still a valid way to proceed.
I'm currently using apollo 3.3 with grandstack and in my component i do the following to perform a mutation (i used useMutation() hook provided by ApolloClient)
const CreateFBUser = gql `
mutation CreateFBUser($name: String, $fbId: String!) {
CreateFBUser(name: $name, fbId: $fbId) {
_id
id
fbId
name
}
}
`
function FbUserForm() {
const { id } = useParams()
const [formState, setFormState] = useState({})
const [createFBUser,{data: createData}] = useMutation(CreateFBUser)
const { loading, error, data } = useQuery(FBUser,{
variables: {_id: id}
});
...
..
.
as you can see, i havent used components like <Query>, and so on..
FIRST QUESTION: is this component related to the apollo old version? are still regulary used or useMutation() hook is the first choice in apollo 3?
SECOND QUESTION: i need to perform a second mutation related to the first, and i need the generated id from the first mutation to execute the second
//the first mutation
const CreateFBUser = gql `
mutation CreateFBUser($name: String, $fbId: String!) {
CreateFBUser(name: $name, fbId: $fbId) {
_id
id
fbId
name
}
}
`
//the second mutation (pseudocode)
const AddFBUserMemberOf = gql`
mutation AddFBUserMemberOf($from: _GroupInput!, $to: _FBUserInput!) {
AddFBUserMemberOf(from: $from, to: $to) {
from
to
}
}
`
moreover, the second mutation should be performed conditionally according to a value/a variable/something else
The render prop components are deprecated and will not receive further updates or bug fixes according to the docs
For your second question; the mutation function returned from useMutation takes an onCompleted property in the options parameter that executes after the mutation successfully completes.
const [createFBUser,{data: createData}] = useMutation(CreateFBUser)
const [addFBUserMemberOf] = useMutation(AddFBUserMemberOf)
createFBUser({
variables: {
//...
},
onCompleted: (data) => {
// data contains the result of createFBUser
addFBUserMemberOf({
variables: {
//...
}
})
}
})

onCompleted callback in useMutation doesn't have return values

I am trying to implement login in react native using apollo.
In react native app
const SIGN_IN = gql`
mutation($username: String!, $password: String!) {
signin(password: $password, username: $username) {
user {
username
}
token
}
}
`;
// code is abbreviated.
function LoginScreen() {
const [signIn, { loading, error }] = useMutation(SIGN_IN, {
onCompleted({ data }) {
if (loading) console.log("Loading.....");
console.log("Printing data");
console.log(data.signin.token);
}
});
}
Backend server is working good.
But I got an error in console log says
[Unhandled promise rejection: TypeError: Cannot read property 'signin' of undefined]
Stack trace:
screens/LogInScreen.js:36:6 in useMutation$argument_1.onCompleted
node_modules/#apollo/react-hooks/lib/react-hooks.cjs.js:635:25 in callOncomplete
data is undefined.
So I tried { data && console.log(data.signin.token) } But it prints nothing.
I read doc says "onCompleted callback to useMutation that will be called once the mutation is complete with its return value."
How can I debug this? what am I missing? Any ideas?
onCompleted is passed the entire data object as its first parameter, so your signature should look like this:
onCompleted(data)
or using destructuring
onCompleted({ signin })

How to update apollo store after making a mutation in react-native? [duplicate]

This question already has an answer here:
Auto-update of apollo client cache after mutation not affecting existing queries
(1 answer)
Closed 3 years ago.
I am new in this apollo graphql and I justtry to understand how this update store works as every time when I make a mutation I have to refresh my app to see the changes. In my following example I am adding a card in my wallet. So to see the new card in my app I have to reload the app.
This part is from AddCard.js where I cand only add the card but I can't see it. So soon as I make the mutation and goBack() my card is not showing until I reload the app.
Any idea how to fix this?
const GET_ME = gql`
query me {
me {
_id
}
}
`;
const GET_WALLET = gql`
query getUserWallet($u_id: ID!) {
getUserWallet(u_id: $u_id) {
_id
}
}
`;
const CREATE_CARD = gql`
mutation($wallet_id: ID!, $cardNo: String!, $exp: String!, $cvc: String!, $card: String! $user: ID!) {
createPayment(wallet_id: $wallet_id, cardNo: $cardNo, exp: $exp, cvc: $cvc, card: $card, user: $user) {
_id
}
}
`;
const mutationConfig = {
props: ({ mutate }) => ({
createPayment: (wallet_id, cardNo, exp, cvc, card, user) => mutate({
variables: { wallet_id, cardNo, exp, cvc, card, user }
}),
})
}
export default compose(
withApollo,
graphql(GET_ME, { name: "getMe" }),
graphql(GET_WALLET, {
name: "getWallet",
options: (props) => (
{
variables:
{
u_id: props.getMe.me._id
}
}
)
}),
graphql(CREATE_CARD, mutationConfig)
)(AddCard);
Apollo's documentation has been updated to use render props rather than the higher order component. If you check out the section on updating the cache it will show you how to do it. It should work similar for your higher order component. You could pass in an update option, which should give you access to the cache. From there, you can write directly to the cache with writeData/writeQuery or you can alter a fragment with writeFragment.
I hope this helps!

Resources