Reputation: 1558
So, I wish to create a GraphQL mutation, in GraphCool, that increments the existing value of an integer field by a predetermined amount, passed in as a variable. For example:
mutation updateLikes ($id: ID!, $count: Int) {
updatePosts (id: $id, likes: incrementBy $count) {
id
likes
}
}
Query variable
{
"id" : "cj0qkl04vep8k0177tky596og",
"count": 1
}
How do I do this?
Also, I am attempting to trigger the above mentioned process from a onClick event, but am getting an 'cannot read property 'props' of null' error message, I suspect on this.props.client.query:
Photo.js
import React from 'react';
import Comments from './Comments';
import CSSTransitionGroup from 'react-addons-css-transition-group';
import { Link } from 'react-router';
import {
gql,
graphql,
withApollo
} from 'react-apollo';
import ApolloClient from 'apollo-client';
class Photo extends React.Component {
incrementQuery(currentID) {
console.log("like of id=" + currentID+ " has been incremented by 1");
this.props.client.query({
query: gql`
mutation updatePosts($id: ID!) {
updatePosts (id: $id, likes: 1) {
id
likes
}
}
`,
variables: {
id: currentID,
},
});
}
render() {
const { post, i } = this.props;
return (
<figure key={i} className="grid-figure">
<div className='grid-photo-wrap'>
<Link to={`/view/${post.id}`}>
<img className='grid-photo' src={post.displaysrc} alt={post.caption} />
</Link>
<CSSTransitionGroup transitionName="like" transitionEnterTimeout={500} transitionLeaveTimeout={500}>
<span key={post.likes} className="likes-heart">{post.likes}</span>
</CSSTransitionGroup>
</div>
<figcaption>
<p>{post.caption}</p>
<div className="control-buttons">
<button onClick={this.incrementQuery.bind(null,i)} className="likes">♥ {post.likes}</button>
<Link to={`/view/${post.id}`} className="button">
<span className="comment-count">
<span className="speech-bubble"></span> {(post.comments ? Object.keys(post.comments).length : 0)}
</span>
</Link>
</div>
</figcaption>
</figure>
)
}
};
Photo.PropTypes = {
client: React.PropTypes.instanceOf(ApolloClient).isRequired,
query: React.PropTypes.object,
variables: React.PropTypes.object,
data: React.PropTypes.shape({
loading: React.PropTypes.bool.isRequired,
error: React.PropTypes.bool.isRequired,
updatePosts: React.PropTypes.object,
}).isRequired,
}
const PhotoWithApollo = withApollo(Photo);
export default PhotoWithApollo;
The thrown error is as follows:
Uncaught TypeError: Cannot read property 'props' of null
at incrementQuery (http://localhost:7770/static/bundle.js:56347:12)
at proxiedMethod (http://localhost:7770/static/bundle.js:54898:31)
at HTMLUnknownElement.wrapped (http://localhost:7770/static/bundle.js:47347:30)
at Object.ReactErrorUtils.invokeGuardedCallback (http://localhost:7770/static/bundle.js:6346:17)
at executeDispatch (http://localhost:7770/static/bundle.js:6146:22)
at Object.executeDispatchesInOrder (http://localhost:7770/static/bundle.js:6169:6)
at executeDispatchesAndRelease (http://localhost:7770/static/bundle.js:5599:23)
at executeDispatchesAndReleaseTopLevel (http://localhost:7770/static/bundle.js:5610:11)
at Array.forEach (native)
at forEachAccumulated (http://localhost:7770/static/bundle.js:6446:10)
at Object.processEventQueue (http://localhost:7770/static/bundle.js:5815:8)
at runEventQueueInBatch (http://localhost:7770/static/bundle.js:6475:19)
at Object.handleTopLevel [as _handleTopLevel] (http://localhost:7770/static/bundle.js:6491:6)
at handleTopLevelWithoutPath (http://localhost:7770/static/bundle.js:16697:25)
at handleTopLevelImpl (http://localhost:7770/static/bundle.js:16677:4)
at ReactDefaultBatchingStrategyTransaction.perform (http://localhost:7770/static/bundle.js:8643:21)
at Object.batchedUpdates (http://localhost:7770/static/bundle.js:12680:20)
at Object.batchedUpdates (http://localhost:7770/static/bundle.js:8148:21)
at dispatchEvent (http://localhost:7770/static/bundle.js:16808:21)
at HTMLDocument.wrapped (http://localhost:7770/static/bundle.js:47347:30)
Upvotes: 2
Views: 5894
Reputation: 1
For the AWS users, I personnaly had the same issue, for an accounting system. The risk with reading and then updating the value is that if several users call your script, some issues of concurrencies might happen. (A user can read the curent value just before it's being updated by another user, so he will arase this other user incrementation). What I did is :
Upvotes: 0
Reputation: 44
Yes. This is a very interesting question. Actually, Apollo client use same method to handle pagination. you must be get current page,when you go to bottom of page, (prev page+1)=>(next page) be a new page variable to get next page content ,then concat to prev page 。 dislike/like,the same way , only difference does't need to concat to prev dike/like. replace it.
Upvotes: -1
Reputation: 7808
Currently you need to first query the value:
query Post($id: ID!) {
Post (id: $id) {
id
likes
}
}
Then increment the likes
client-side and update the post with the new value for likes
:
mutation updateLikes ($id: ID!, $likes: Int!) {
updatePost (id: $id, likes: $likes) {
id
likes
}
}
Incrementing the likes by a special number is a great use case for a custom mutation, which we are already working on.
Upvotes: 3