facebook / facebook/relay

how to optimistic response a connection property in mutation?

Open
#2,794 5 comments 0 reactions 0 assignees View on GitHub
wontfix
Dominant language
Rust
Stars
19k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

i have a comments connection in a mutation, this is the query:
```
export default mutationFromQuery(graphql`
mutation AddBookMutation($input: AddBookInput! $count: Int $cursor: String ) {
addBook(input: $input) {
book {
__typename
cursor
node {
id
title
owner
createdAt
comments(first: $count, after: $cursor)
@connection(key: "BookComments_comments") {
__typename
edges {
node {
id
}
}
}
}
}
}
}
`)
```

This is how i did my optimisticUpdater that don't work:

```
optimisticUpdater: (store) => {
const userProxy = store.get(viewerId)
const owner = userProxy.getValue('username')
const id = uuidv1();
const book = store.create(id, 'Book');
book.setValue(id, 'id');
book.setValue(bookTitle, 'title');
book.setValue(owner, 'owner');
book.setValue(Date.now(), 'createdAt');
const comments = store.create(uuidv1(), 'comments', { count: null, cursor: null }) // initial args from component
comments.setLinkedRecords([], 'edges')
const pageInfo = store.create(uuidv1(), 'pageInfo')
pageInfo.setValue(null, 'endCursor')
pageInfo.setValue(false, 'hasNextPage')
pageInfo.setValue(false, 'hasPreviousPage')
pageInfo.setValue(null, 'startCursor')
comments.setLinkedRecord(pageInfo, 'pageInfo')
book.setLinkedRecord(comments, 'comments')
const bookEdge = store.create(uuidv1(), 'BookEdge');
bookEdge.setLinkedRecord(book, 'node', { id } ); // tried this for the comments to detect the book node
console.log('bookEdge ', bookEdge)
booksUpdater(userProxy, bookEdge);
},
```

The problem i have is that comments always ends up on undefined as you can see above i've already set it. I also did this but i am still not getting an optimistic UI:

```
optimisticResponse: {
addBook: {
book: {
__typename: 'BookEdge',
cursor: uuidv1(),
node: {
id: uuidv1(),
title: bookTitle,
owner: username,
createdAt: Date.now(),
comments: {
__typename: 'CommentConnection',
edges: [],
pageInfo: {
endCursor: null,
hasNextPage: false
}
}
}
}
}
},
```
App don't crash with optimisticResponse code but no optimistic UI effect, but with the optimisticUpdater it's crashing with comments being undefined, for now I am settling with my updater:

```
updater: (store) => {
const userProxy = store.get(viewerId)
const payload = store.getRootField('addBook');
booksUpdater(userProxy, payload.getLinkedRecord('book'));
},
```

since the comments is undefined I guess we cannot use this for optimistic effect:

```
const comments = store.create(uuidv1(), 'comments')
comments.setLinkedRecords([], 'edges')
book.setLinkedRecord(comments, 'comments')
```

on my Book, this is the query which has the comments fragment that is undefined on optimistic update with the code above:

```
export default createRefetchContainer(
BookItem,
{
book: graphql`
fragment BookItem_book on Book
@argumentDefinitions(
count: { type: "Int", defaultValue: 5 }
cursor: { type: "String", defaultValue: null }
) {
id
title
owner
createdAt
...BookComments_book
}
`
},
graphql`
query BookItemQuery($id: ID!, $count: Int, $cursor: String) {
book: node(id: $id) {
...BookItem_book @arguments(count: $count, cursor: $cursor)
}
}
`
);
```

and now the query for the comments component where it gets the book.comments.edges is undefined:

```
export default createPaginationContainer(
BookComments,
{
book: graphql`
fragment BookComments_book on Book
@argumentDefinitions(
count: { type: "Int", defaultValue: 3 }
cursor: { type: "String", defaultValue: null }
) {
id
title
comments(first: $count, after: $cursor)
@connection(key: "BookComments_comments", filters: []) {
__typename
edges {
node {
id
text
owner
createdAt
}
}
pageInfo {
startCursor
endCursor
hasPreviousPage
hasNextPage
}
}
}
`
},
{
direction: 'forward',
getConnectionFromProps: (props) => props.book && props.book.comments,
getFragmentVariables: (prevVars, totalCount) => ({
...prevVars,
count: totalCount
}),
getVariables: (props, { count, cursor }, _fragmentVariables) => ({
count,
cursor,
id: props.book.id
}),
query: graphql`
query BookCommentsQuery($id: ID!, $count: Int, $cursor: String) {
book: node(id: $id) {
...BookComments_book @arguments(count: $count, cursor: $cursor)
}
}
`
}
);
```

maybe this is an anti pattern? but i just wanted to have a optimistic effect for this

Contributor guide

Open the contributing guide

Research direction

Start at the mutation's optimisticUpdater and optimisticResponse, then compare them with the BookItem_book and BookComments_book fragments and the BookComments pagination entry points. Trace how the BookComments_comments connection is keyed and read, and verify that the optimistic record matches the fragment shape and renders before the server response.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, javascript, react
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.