I don't know if it's an issue, I'm new to Relay.. After doing the mutation in relay modern,
const mutation = graphql`
mutation addPostMutation (
$input: addPostData!
) {
addPost(data: $input) {
node {
id
content
}
}
}
`;
commitMutation(
environment,
{
mutation,
variables,
onCompleted: (res) => {
console.log(environment)
console.log(res)
},
onError: err => console.error(err)
}
)
when I console.log environment, I can see the newly added post in the relay store, but it's not updated in the UI. However, after refreshing the app, the changes are made. This is my schema.graphql
schema {
query: Root
mutation: Mutation
}
type Mutation {
addPost(data: addPostData!): addPostMutation
}
input addPostData {
userID: String,
post: String,
tags: [String]
}
type addPostMutation {
node: postNode
}
interface Node {
id: ID!
}
type postEdges {
node: postNode
}
type postNode implements Node {
id: ID!
content: String
}
cc @kassens - I'm not sure how mutations interact with lists of values. I think since the "post" you added was not in the UI before the mutation that it does not update by default.
However it's also unclear from your example what's going on. For example, what uses the postEdges type? Where is your Root type?
schema {
query: Root
mutation: Mutation
}
type Root {
AllPosts: getPostsQuery
node(id: ID!): Node
}
type Mutation {
addPost(data: addPostData!): addPostMutation
}
interface Node {
id: ID!
}
input addPostData {
userID: String,
post: String,
tags: [String]
}
type addPostMutation {
node: postNode
}
type getPostsQuery {
edges: [postEdges]
}
type postEdges {
node: postNode
}
type postNode implements Node {
id: ID!
content: String
}
Yes of course it was not in the UI before. I want the list of post to update as I add the post. Though it only updates after I refresh the page.
Yeah I guess but can't really figure it out how to update the store passed in the updater.
The response is normalized in the store, but it is not appended in getPostsQuery
Basically, you want something like this
const updater = proxyStore => {
const newEdgeNode = proxyStore.getRootField('addPost'),
// since 'AllPosts' is under Root
const prevPosts = proxyStore.getRoot().getLinkedField('AllPosts');
const prevEdgeNodes = prevPosts && prevPosts.getValue('edges');
if (prevEdgeNodes) {
prevEdgeNodes.push(newEdgeNode); // You might want to append or prepend
prevPosts.setLinkedRecords(prevEdgeNodes, 'edges');
}
}
@JenniferWang Thanks for the example! I'm a bit confused on how proxyStore.getRootField('addPost') == newEdgeNode. I guess it seems a little unintuitive that getRootField somehow pulls the result of a mutation?
ah, we have a pretty bad naming for this. I am not super sure if this is the case, but if you print out the store in onComplete callback(when the changes are committed to the store), you should be able to see a key for the top-level normalized record for the mutation payload under root -- since we need a systematic way to create a key for the payload, a natural choice is under root and that's why it's named as getRootField.
Thanks for the update...
proxyStore.getRoot().getLinkedField() is not a function. Can you refer to any docs?
Should be getLinkedRecord
This is a good place to lookup all the API on the proxy store/record
https://github.com/facebook/relay/blob/master/packages/relay-runtime/store/RelayStoreTypes.js#L150-L174
yeah right. What other approach can we use other than manually updating the store?
I'm trying to do the same thing and have been playing around with the updater function example (thanks @JenniferWang). I can't get it to work though. const prevEdgeNodes = prevPosts && prevPosts.getValue('edges'); gives this error:
Error: RelayModernRecord.getValue(): Expected a scalar (non-link) value for 'client:root:AllPosts.edges' but found plural linked records.
(I updated the naming in this example to follow @saudpunjwani101's schema. Obviously I have different fields and names in my schema).
Has anyone else come across this? I'm reading the source but haven't been able to figure out what I'm doing wrong yet.
@erikfrisk try doing const prevEdgeNodes = prevPosts && prevPosts.getLinkedRecords('edges'); it worked for me
@saudpunjwani101 Thanks! That got me a little further. I had the idea to try getLinkedRecord yesterday but not getLinkedRecords :)
Now I'm no longer getting errors in the console but the UI still isn't updating. Did you manage to get it to work all the way?
Yeah make sure you append the data.
I thought I was doing that. Here's my updater function. Can you tell what I'm doing wrong?
updater: (store) => {
const newEdgeNode = store.getRootField('createReport');
const prevReports = store.getRoot().getLinkedRecord('reports');
const prevEdgeNodes = prevReports && prevReports.getLinkedRecords('edges');
if (prevEdgeNodes) {
prevEdgeNodes.unshift(newEdgeNode);
prevReports.setLinkedRecords(prevEdgeNodes, 'edges');
}
},
reports in my schema is basically the equivalent of AllPosts in your schema. The relevant parts of my schema:
input CreateReportInput {
name: String!
language: String
clientMutationId: String
}
type CreateReportPayload {
report: Report
clientMutationId: String
}
type Mutation {
createReport(input: CreateReportInput!): CreateReportPayload
}
# An object with an ID
interface Node {
# The id of the object.
id: ID!
}
# Information about pagination in a connection.
type PageInfo {
# When paginating forwards, are there more items?
hasNextPage: Boolean!
# When paginating backwards, are there more items?
hasPreviousPage: Boolean!
# When paginating backwards, the cursor to continue.
startCursor: String
# When paginating forwards, the cursor to continue.
endCursor: String
}
type Query {
# Fetches an object given its ID
node(
# The ID of an object
id: ID!
): Node
reports(after: String, first: Int, before: String, last: Int): ReportConnection
}
type Report implements Node {
# The ID of an object
id: ID!
mongoId: ID
name: String
language: String
}
# A connection to a list of items.
type ReportConnection {
# Information to aid in pagination.
pageInfo: PageInfo!
# A list of edges.
edges: [ReportEdge]
}
# An edge in a connection.
type ReportEdge {
# The item at the end of the edge
node: Report
# A cursor for use in pagination
cursor: String!
}
the code looks okay to me. Can u console.log the prevReports to see if the new node actually appeared in the store?
I think I'm starting to see the problem. I did what you said @saudpunjwani101 and noticed that the new node looked different than the others when i logged prevReports. I guess the updater function I'm using is grabbing the mutation payload and trying to add that as an edge on the report connection. The problem is it's not the right type. The mutation payload (newEdgeNode?) is this...
type CreateReportPayload {
report: Report
clientMutationId: String
}
... and prevEdgeNodes that I'm prepending to is an array of this...
type ReportEdge {
# The item at the end of the edge
node: Report
# A cursor for use in pagination
cursor: String!
}
Makes sense that it doesn't work. I can get the report itself from the mutation payload by doing newEdgeNode.getLinkedRecord('report'). Now I just need to figure out how to manually create a new ReportEdge in the updater function so that I can add the new report to the ReportEdge's node field and add the ReportEdge to the ReportConnection. Does anyone reading this know how to do that? 😄
@saudpunjwani101: I see that your mutation payload has a node field, which I guess makes it work in your case. Doesn't the mutation payload also need to have a clientMutationId field in order to be Relay compliant?
Also, this all seems pretty complex for a very common use case. Is this going to be simplified in future releases of Relay Modern or am I just finding it difficult because I'm a n00b?
Yes, this is not correct.
prevEdgeNodes.unshift(newEdgeNode);
It would be helpful if you could append your mutation here. Generally there will be three cases for a connection field.
@connection(key: 'someKey'), then you should be able to use RelayConnectionHandler to delete the edge (if you know the node id)report(first: 3), then in your mutation query, you probably want to refetch the whole thing, relay will update the store automatically (you don't need to supply an updater function)updater function like in 1.Thanks for the info @JenniferWang. Do you mean append the mutation as described by the schema?
input CreateReportInput {
name: String!
language: String
clientMutationId: String
}
type CreateReportPayload {
report: Report
clientMutationId: String
}
type Mutation {
createReport(input: CreateReportInput!): CreateReportPayload
}
(I also posted my full schema in a previous post.)
The mutation itself doesn't do anything special right now (I think):
import {commitMutation, graphql} from 'react-relay';
import environment from 'data/environment';
const mutation = graphql`
mutation CreateReportMutation(
$input: CreateReportInput!
) {
createReport(input: $input) {
report {
id
mongoId
name
language
}
}
}
`;
function commit({name, language}) {
commitMutation(
environment,
{
mutation,
variables: {
input: {
name,
language,
},
},
// updater: (store) => {
// // Do some magic that I haven't figured out yet.
// },
},
);
}
export default {commit};
Right now the reports are just fetched and shown in a component without taking advantage of the fact that they're in a connection. The fact that they're in a connection is more to make it future-proof as I build out the web app. This is my ReportList component (with some irrelevant bulk cut out):
import React, {Component} from 'react';
import {createFragmentContainer, graphql} from 'react-relay';
import RaisedButton from 'material-ui/RaisedButton';
import {Link} from 'react-router-dom';
import CreateReportMutation from 'mutations/CreateReportMutation';
class ReportList extends Component {
addReport() {
CreateReportMutation.commit({
name: 'My Report',
language: 'en',
});
}
render() {
const reports = this.props.reports.edges.map((edge) =>
<li key={edge.node.id}>
<Link to={`/reports/${edge.node.id}`}>
{edge.node.name} ({edge.node.mongoId})
</Link>
</li>
);
return (
<div>
<RaisedButton
label="Add report"
primary={true}
onTouchTap={this.addReport}
/>
<ul>
{reports}
</ul>
</div>
)
}
}
export default createFragmentContainer(
ReportList,
graphql`
fragment ReportList_reports on ReportConnection {
edges {
node {
id
mongoId
name
}
}
}
`,
);
"Refetching the whole thing" sounds good. How do I do that in Relay Modern? The only thing I can find in the documentation is the RefetchContainer, but that seems to be meant for more advanced situations, right?
@erikfrisk I believe I was running into the same issue you are/were experiencing – adding a new edge to a connection. This example helped me get there:
The secret sauce (as Jennifer alluded too) was to import {ConnectionHandler} from 'relay-runtime' and use it as the example demonstrates.
I also had to restructure my fragment some using this related example as a guide:
Thanks @cipater! That, plus reading the RelayConnectionHandler source, gave me the last bits I needed. It works now! 😄
Posting my solution here for others. This is my updater function:
import {ConnectionHandler} from 'relay-runtime';
...
updater: (store) => {
const payload = store.getRootField('createReport');
const newReport = payload.getLinkedRecord('report');
const storeRoot = store.getRoot();
const connection = ConnectionHandler.getConnection(
storeRoot,
'ReportList_reports',
);
const newEdge = ConnectionHandler.createEdge(
store,
connection,
newReport,
'ReportEdge',
);
ConnectionHandler.insertEdgeBefore(connection, newEdge);
},
The fragment in my ReportList component:
export default createFragmentContainer(
ReportList,
graphql`
fragment ReportList_query on Query {
reports(
first: 2147483647 # max GraphQLInt
) @connection(key: "ReportList_reports") {
edges {
node {
id
mongoId
name
}
}
}
}
`,
);
@JenniferWang how do u refetch the whole thing? is there like a props.refetch method in relay like Apollo client?
@saudpunjwani101 use the RefetchContainer?
https://facebook.github.io/relay/docs/refetch-container.html
@saudpunjwani101 A common practice is to have a structure such as:
RefetchContainer // to refetch the connection in-full when filter arguments change
PaginationContainer // to fetch more items with the same filter arguments
Array<FragmentContainer> // to render each edge
hmm, I don't think @saudpunjwani101 is asking about pagination container.
What I mean by "refetch" is that you could refetch the connections in the mutation payload. However, this involves changes in your current schema. I'm not sure how to modify your schema, but we usually have
type Query {
# ...
viewer: Viewer
}
type Viewer {
# ...
reports(after: String, first: Int, before: String, last: Int): ReportConnection
}
type Mutation {
createReport(input: CreateReportInput!): CreateReportPayload
}
type CreateReportPayload {
report: Report
clientMutationId: String
viewer: Viewer
}
Then the query fragment will be
graphql`
fragment ReportList_viewer on Viewer {
reports(
first: 20 # I don't think a max int makes sense
) {
edges {
node {
id
mongoId
name
}
}
}
}
`,
And the mutation will be
mutation CreateReportMutation(
$input: CreateReportInput!
) {
createReport(input: $input) {
viewer {
...ReportList_viewer # You could use fragment spread here
}
}
}
Then there is no need to have your updater function. The one downside of this is that it will be cumbersome to provide an optimistic response.
In your case, if you really want to fetch many edges in the query, then it makes sense to use @connection and give a customized updater function because it will be too costly to fetch everything again in the mutation. In that case, you could just fetch the newly created edge and use helper functions in RelayConnectionHandler to update the client side (and this is exactly what you are doing now).
yeah that answers to it
@JenniferWang how do i get the viewer object in Root Query.
PS the viewer object does not have a unique ID.
store.getRoot().getLinkedRecord('viewer') does not work
my structure is like this:
query{
viewer{
user{ id firstName LastName}
feed1{ edges{node{id}}} @connection(key: 'someKey')
feed2{ edges{node{id}}} @connection(key: 'someKey2')
}
}
i need to get the store to update someKey
@stoffern I'm not sure whether you are using RelayViewerHandler. If you use that, the viewer object could be accessed as a node
store.get(VIEWER_ID)
If you are not using it, I think store.getRoot().getLinkedRecord('viewer') should have worked? You could also dump the store proxy by the following code to see what does the store look like at that point. It is also possible that you haven't fetched a query that ask for viewer yet.
const updater = (store) => {
require('RelayStoreProxyDebugger'). dump(store);
}
Neighter work.
I have tried and the store is:
client:root:viewer:__Feeds_feedClosest_connection{}
__Update__
It is my args that are the issue. Seems i have a problem with dynamic args.
created a separate issue here: https://github.com/facebook/relay/issues/1764
Just giving this a bump as we are having the same problem.
There is no clarity on how to update your UI on a Mutation. The only source of information we have is from GitHub.
We do not use an edge/node schema in the same way that the Facebook Todo example does, thus making it incredibly difficult to find any indication of the way to update our store and UI with a successful mutation.
Most of all, it isn't clear why the UI doesn't refresh with the store changes using :
const updater = (store) => {
let rootField = store.getRootField(`createFundingSource`)
store.getRoot().copyFieldsFrom(rootField)
}
Would be good to have some clearer documentation on the mutations and updaters.
I had a similar problem: I needed to update specific query when mutation was committed. I had this query in my header component
Person(where: $where) {
id
title
firstName
middleName
lastName
gender
}
where = { id: { eq: '7' } }
So in relay store there was record Person{"where":{"id":{"eq":"7"}}} and it was null.
In my mutations config in updater function i wrote this:
(store) =>
const record = store.get(store.getRootField('login').getLinkedRecord('user').getValue('id'));
store.getRoot().setLinkedRecords([record], 'Person', { where: { id: { eq: '7' } } })
my mutations response looks like this: { login: { user: { id: .....} } }
I know it's very specific case but now it's possible to work with it further. Basically the idea is to get whatever comes from the server find the needed record in the relay store and just reset it.
Or if you have MeQuery query all you need to do to update it in relay store is store.getRoot().setLinkedRecord(record, 'MeQuery');
I got struck with this problem where it didn't update the UI in React-native App but work in Web.
Thank you @erikfrisk for saving my time not to move to Apollo.
check this post https://medium.com/entria/wrangling-the-client-store-with-the-relay-modern-updater-function-5c32149a71ac by @ssomnoremac
Hi, I am running into the same issue here (relay 1.4.0). I'm using the viewer pattern, but I am NOT using connections and pagination as I don't require that at the moment.
The mutation I am performing gets correctly updated into the relay store, and is correctly inserting records through my updater function, but Relay never automatically updates the UI.
My work around at the moment is to run a completed callback which runs setState on the component to manually update the UI. I am happy with that for now. But it would be nice to know how to get Relay to update the UI after a mutation is successfully performed?
For anyone interested here is how my updater and onCompleted function looks like. is there anything I am missing here?
Also I am using found-relay for my routing. I haven't heard this mention by anyone. But wondering if this is an element tat could be affecting this issue as well?
Example graphQL mutation input:
mutation CreateTimerMutation($input: CreateTimerInput!){
createTimer(input: $input) {
createdTimer{
id,
name,
parentTimerId
}
}
}
Example graphQL mutation payload:
{
"data": {
"createTimer": {
"createdTimer": {
"id": "534bec16-42c6-4e09-806c-10a2ac5680f8",
"name": "New timer 3",
"parentTimerId": null
}
}
}
}
Updater and onCompleted mutation configs:
updater(store) {
const payloadProxy = store.getRootField('createTimer');
const createdTimerProxy = payloadProxy.getLinkedRecord('createdTimer');
const viewerProxy = store.getRoot().getLinkedRecord('viewer');
const timersProxy = viewerProxy.getLinkedRecords('timers');
if(timersProxy){
timersProxy.push(createdTimerProxy)
viewerProxy.setLinkedRecords(timersProxy, 'timers')
}
},
onCompleted(response, errors) {
//this runs setState on the component with the update data from viewer
//I'd rather Relay update the UI automatically
completed()
}
Schema: here's the related schema with relevant sections included:
interface Node {
id: ID!
}
schema {
query: Query
mutation: Mutation
}
type Query {
viewer: User
}
type Mutation {
createTimer(input: CreateTimerInput!): CreateTimerMutationPayload
}
type User implements Node {
id: ID!
timers: [Timer!]!
}
type Timer implements Node {
id: ID!
parentTimerId: ID
name: String
...
}
input CreateTimerInput {
parentTimerId: ID
name: String
...
clientMutationId: String
}
type CreateTimerMutationPayload {
createdTimer: Timer
clientMutationId: String
}
My query on the component
```
export const AdminTimersQuery =
graphql
query adminTimers_Query {
viewer {
id
...adminTimers_viewer
}
}
`;
````
and the related fragment...
```
export default withRouter(createFragmentContainer(
AdminTimers,
graphql
fragment adminTimers_viewer on User {
timers {
id,
name,
parentTimerId
}
}
`));
````
Hi, i am having the same issue of relay store getting updated but my UI is not updating. Its getting updated if i refresh the page.
This is my CreateChatMutation file where i am running createChat mutation and rendering the data using QueryRenderer:
import {commitMutation, graphql} from 'react-relay'
import {ConnectionHandler} from 'relay-runtime'
import environment from './Environment'
import LinkList from './LinkList'
// import storeDebugger from 'relay-runtime/lib/RelayStoreProxyDebugger'
const mutation = graphql`
mutation CreateChatMutation($input: CreateChatInput!){
createChat(input: $input){
chat{
id
from
content
createdAt
}
}
}`
let temp =0
export default (from, content, callback) => {
const variables = {
input: {
from,
content,
clientMutationId:""
},
}
commitMutation(
environment,{
mutation,
variables,
onCompleted: (response)=>{
console.log('response: ', response);
const id = response.createChat.chat.id;
callback(response);
},
updater: proxyStore => {
//
// // storeDebugger.dump(proxyStore)
//
const payload = proxyStore.getRootField('createChat');
console.log('updater: payload : ',payload);
const newReport = payload.getLinkedRecord('chat');
console.log('updater: newReport : ',newReport);
const storeRoot = proxyStore.getRoot();
console.log('updater: storeRootss : ',storeRoot);
// storeRoot.setValue(payload.getLinkedRecord('chat').getValue('from'), from);
// storeRoot.setLinkedRecord()
// console.log('updater: storeRootinggg : ',storeRoot);
const connection = ConnectionHandler.getConnection(
payload,
'LinkList_allChats'
);
console.log('updater: connection : ',connection);
const newEdge = ConnectionHandler.createEdge(
proxyStore,
connection,
payload,
'ChatEdge'
);
console.log('updater: newEdge : ',newEdge);
ConnectionHandler.insertEdgeBefore(connection, newEdge);
},
// console.log('one:',prevPosts)
onError: err => console.error(err),
},
)
}
This is my LinkList file which i am using in CreateChatMutation:
import React, {Component} from 'react'
import Link from './Link'
import {createFragmentContainer, graphql} from 'react-relay'
class LinkList extends Component{
render() {
return(
<div>
{
this.props.viewer.allChats.edges.map(({node}) =>
<Link key={node.__id} link={node}/>
)}
</div>
)
}
}
export default createFragmentContainer(LinkList, graphql`
fragment LinkList_viewer on Viewer{
allChats(last: 100, orderBy: createdAt_ASC) @connection(key:"LinkList_allChats", filters:[]){
edges{
node{
...Link_link
}
}
}
}`)
Any help would be appreciated. Thanks
we have this helpers to update connections
export function connectionUpdater({ store, parentId, connectionName, edge, before, filters }) {
if (edge) {
if (!parentId) {
// eslint-disable-next-line
console.log('maybe you forgot to pass a parentId: ');
return;
}
const parentProxy = store.get(parentId);
const connection = ConnectionHandler.getConnection(parentProxy, connectionName, filters);
if (!connection) {
// eslint-disable-next-line
console.log('maybe this connection is not in relay store yet:', connectionName);
return;
}
if (before) {
ConnectionHandler.insertEdgeBefore(connection, edge);
} else {
ConnectionHandler.insertEdgeAfter(connection, edge);
}
}
}
Usage:
const newEdge = store.getRootField('createChat').getLinkedRecord('chatEdge');
connectionUpdater({
store,
parentId: viewer.id,
connectionName: 'LinkList_allChats',
edge: newEdge,
before: true,
});
Returning an edge from mutation makes things easier, but you could also create the edge on client
Thanks for that, but what is viewer.id?. Please don't mind me asking simple questions as i am completely new to react and relay. You can look at the viewer code that i have put above in LinkList class
Can anyone please put some light on (viewer.id). I am stuck from last 4 days.
Viewer.id is the global id of your graphql query. It should be the root of
all your query objects.
On Tue, 5 Feb 2019 at 10:35 PM, Prashanth Verma notifications@github.com
wrote:
Can anyone please put some light on (viewer.id). I am stuck from last 4
days.—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/facebook/relay/issues/1701#issuecomment-460683383,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ASVaNS2SBrf-Vx9Ek16FYYfbRhOzTMVfks5vKaTcgaJpZM4NKLAX
.
fragment LinkList_viewer on Viewer {
id
allChats
}
You should avoid viewer anyway, it a old and bad pattern, used only on relay classic
When using fragments on QueryType, the parent of the connection is ROOT_ID
import { ROOT_ID } from 'relay-runtime';
So I import ROOT_ID from relay-runtime and can pass ROOT_ID instead of viewer.id?
only if you have something like this
fragment LinkList_query on Query {
allChats(...) @connection
}
You should avoid viewer anyway, it a old and bad pattern, used only on relay classic
@sibelius Just out of curiosity - why is it a bad pattern? (I never actually used it) I always thought it's quite nice to have this extra level where you can deal with all the auth and other _viewer_ specific issues (for example whitelabel version so you don't have to send it in headers or to every query).
Use me field to represent logged user, passing auth token on header makes more sense, so u have one less variables in all queries and mutation
I'm having the same issue with QueryRenderer on React Native re-rendering with outdated props after the mutation updater has been called, and the store has been updated properly.
Note: I'm not using connections – could it be that QueryRenderer is re-fetching when new edges/nodes are connected?
// Schema extract
User {
id: ID!
data: [ Data! ]!
}
mutation {
store(input: DataCreateManyInput!): User!
}
// Updater function
const payload = store.getRootField('store')
const userProxy = store.get(payload.getValue('id'))
const data = payload.getLinkedRecords('data')
userProxy.setLinkedRecords(data, 'data')
// React fragment container
const DataFragmentContainer = createFragmentContainer(
Data,
graphql`
fragment data_user on User {
id
data(orderBy: date_ASC) {
type
unit
date
value
user {
id
}
}
}
`,
)
export default ({ navigation }) => {
return (
<QueryRenderer
environment={Environment}
query={graphql`
query dataQuery {
viewer {
...data_user
}
}
`}
render={({ error, props }) => {
let viewer = props && props.viewer
return <DataFragmentContainer user={viewer} navigation={navigation} />
}}
/>
)
}
check if your QR is not re-rendering
I think navigation prop change and QR will rerender with stale data
The QR is re-rendering, but with stale data indeed. Is there a workaround?
avoid rerender QR
Hello, I was having the same problem.. but @JenniferWang helped me a lot!!
Here is what I was trying to do... I have two input fields to register a user and a list to show the users, when I insert a new user I wanted to display the just inserted user in that list. Here's my (and @JenniferWang) solution if anyone is having any problems..
My QueryRenderer
<QueryRenderer
environment={environment}
query={query}
render={(result: any) => {
const users =
result.props === null ? null : result.props.PedroBotelho
return (
<div className="App-header">
<Form users={users}/>
<List users={users}/>
</div>
)
}}
/>
My commitMutation
commitMutation(environment, {
mutation: mutation,
variables: {
name: values.name,
lastName: values.lastName,
},
updater: (store: any, data: any) => {
**const prevPosts = store.getRoot().getLinkedRecords('PedroBotelho')
prevPosts.push(store.getRootField('PedroBotelhoAdd'))
store.getRoot().setLinkedRecords(prevPosts, 'PedroBotelho')**
}
})
PedroBotelho is the name of my graphql query and PedroBotelhoAdd is my mutation.
Most helpful comment
Just giving this a bump as we are having the same problem.
There is no clarity on how to update your UI on a Mutation. The only source of information we have is from GitHub.
We do not use an edge/node schema in the same way that the Facebook Todo example does, thus making it incredibly difficult to find any indication of the way to update our store and UI with a successful mutation.
Most of all, it isn't clear why the UI doesn't refresh with the store changes using :
Would be good to have some clearer documentation on the mutations and updaters.