I've been trying Apollo out with React and am currently facing a problem with it.
I have basic data where a Product belongs to many Categories
query getProduct{
product(id: 1){
id
name
categories{id,name}
}
}
As expected this returns something like this
{
"data": {
"p": {
"id": 1,
"name": "Samsung Galaxy S7",
"categories": [
{
"name": "Phone"
},
{
"name": "Samsung"
}
]
}
}
}
Here is my react Component
class TileProductComponent extends Component{
constructor(...args){
super(...args)
}
render(){
if(this.props.data.loading)
return <div>Loading...</div>
var product = this.props.data.p
console.log(this.props.data)
return (
<div> {product.name} </div>
)
}
}
var TileProduct = graphql(
gql`
query TestQuery($id: Int!){
product(id: $id){
id
name
categories{id,name}
}
}
`,
{
options : {
variables : {id:1}
}
}
)(TileProductComponent)
But once it is passed in the react component i found it to be (from the console.log(this.props.data))
"product": {
"id": 1,
"name": "Phone",
"categories": [
{
"name": "Phone"
},
{
"name": "Samsung"
}
]
}
The product name adopts the name of the first category for some reason ? I'm guessing the id will too. A fix would be to change the name of fields in the schemas, but it shouldn't really do that anyway in my opinion.
Is this a known issue or am I the only one experiencing this? Any proposed solution ?
The problem is with your dataIdFromObject
function. This function needs to return a unique value for different objects that come from the server. One easy way to do this is to use the __typename
field built into GraphQL with your ID field. Here's a code snippet:
const client = new ApolloClient({
queryTransformer: addTypename,
dataIdFromObject: (result) => {
if (result.id && result.__typename) {
return result.__typename + result.id;
}
return null;
}
});
To see it used in the context of an app, check out the GitHunt frontend example, which uses SQL incremental IDs: https://github.com/apollostack/GitHunt-React/blob/380bedaef97f2a0932c1ab33bd964812d4a8a65e/ui/client.js#L42-L48