3

I am using a QueryRenderer to populate an edit form in my application. The data is also being displayed in additional DOM elements throughout the page. I am then saving the values back on form submit through a mutation. Everything works great, except for the fact that my UI is not reflecting the changes afterwords. Here is my initial query:

    query EditPlanDialogQuery($planId: Int!) {
        planByPlanId(planId: $planId) {
            nodeId
            ...fields
        }
        allSchedules {
            nodes {
                ...fields
            }
        }            
    }

Then my mutation and wrapper function are defined as follows:

    mutation EditPlanDialogMutation($input: UpdatePlanInput!) {
        updatePlan(input: $input) {
            plan {
                ...fields
            }
        }
    }

...

    editPlan = (values: any) => {
        const {
            nodeId,
            ...otherValues
        } = values;
        const variables = {
            input: {
                nodeId: nodeId,
                planPatch: { ...otherValues },
            },
        };
        commitMutation(
            environment,
            {
                mutation,
                variables,
                onCompleted: (response, errors) => alert(response),
                onError: err => alert(err),
            }
        );
    }

Again, the data is being saved to the database properly, however the other DOM elements that are displaying the data are not rendered to reflect the changes. I thought for simple updates Relay handled this? According to their docs anyway this should be the case. I tried messing with the updater callback, and ultimately got the page to update, but it seemed very clunky. Any advice is appreciated, thanks!

Sloth Armstrong
  • 1,066
  • 2
  • 19
  • 39
  • 2
    When I had issues like this it was generally due to 2 things: 1) the item data used in the frontend was not being returned as the mutation payload (i.e id); 2) in the component the relay prop was not being directly used to render the content, instead, it was stored in the state or any other variable, so the prop.relay was updated but the state was not. Try to check if any of this is your case. Let me know if it helped – soutot Apr 12 '18 at 23:03
  • @soutot Thanks for the input. Can you elaborate on your first point? As for the second, I am passing the relay prop into child components and using it directly for rendering. Thanks again! – Sloth Armstrong Apr 13 '18 at 00:15
  • Sure! In the first case, I meant that when you write the GraphQL of your mutation you can add a payload to it, it means that just after the mutation is completed it will return whatever data you requested in your payload. For example, let's say you have triggered an AddUserMutation, the payload can be the id and the name of the user, which are existing fields in your model. However, if you don't use this payload in your frontend (i.e you just display user email), your data will not be updated after mutation is completed. Note that "use in frontend"means it is not requested by your graphql – soutot Apr 13 '18 at 14:08
  • Feel free to ask if it was not clear. Hope it helps – soutot Apr 13 '18 at 14:09

1 Answers1

2

Not sure what fields you're getting, but I guess you don't get id from the mutation. You always have to ask for node's id, so relay can match updated nodes in the store. And node's id have to be named id (not nodeId)

mutation EditPlanDialogMutation($input: UpdatePlanInput!) {
    updatePlan(input: $input) {
        plan {
            id
            ...fields
        }
    }
}
BorisTB
  • 1,686
  • 1
  • 17
  • 26