Originally posted by @jordan-burnett at https://github.com/apollostack/react-apollo/issues/124
When using multiple fragments, I'm finding that nested fields aren't being resolved to props as expected.
For example, I have a query attached to a connected component like:
neighbourhoods{
name
...fragmentOne
...fragmentTwo
}
with two fragments like:
fragment fragmentOne on Neighbourhood {
population
city {
name
}
}
fragment fragmentOne on Neighbourhood {
city {
countryName
}
}
I can see in the server response city.name and city.countryName is returned as expected for each neighbourhood, but my component only seems to receive the data from the first fragment in it's props and I'm only able to see city.name. Is this the expected behaviour?
Here's a concise reproduction also by @jordan-burnett:
No problem, here's a compressed version of the code I'm using which I've just tested produces the same result:
const fragmentOne = createFragment(gql`
fragment fragmentOne on Neighbourhood {
name
city {
name
population
}
}
`);
const fragmentTwo = createFragment(gql`
fragment fragmentTwo on Neighbourhood {
id
city {
countryName
image
}
}
`);
function mapQueriesToProps({ ownProps, state }) {
return {
neighbourhood: {
query: gql`
query neighbourhoodData($slug: String!) {
data: neighbourhood(slug: $slug) {
title
subtitle
...fragmentOne
...fragmentTwo
}
}`,
variables: {
slug: ownProps.params.slug,
},
fragments: [...fragmentOne, ...fragmentTwo]
},
};
};
class Component extends React.Component {
render() {
if(this.props.neighbourhood.data) {
const data = this.props.neighbourhood.data;
console.log(data); // <-- Here city only contains 'name' and 'population'
}
return null;
}
}
const ConnectedComponent = connect({
mapQueriesToProps
})(Component);
The order in the root query changes the output. If I place fragmentTwo first then city contains 'countryName' and 'image'
Probably related? @stubailo #544
Also running into same issue; I've looked into this a bit deeper and found that the data object will only contain the nested properties of the last fragment:
fragment userProfile1 on User {
profile {
name
}
}
/* Example One */
query users {
profile {
email
}
...userProfile1
}
// Result =>
data.users[0].profile === { name: 'Some Name' } // <- no email field
/* Example Two */
query users {
...userProfile1
profile {
email
}
}
// Result =>
data.users[0].profile === { email: 'some@email' } // <- no name field
The query to the server is correct, data returned by the server is correct, Data in redux/apollo store is correct! Data returned by client, is incorrect.
The fact that the data is in the redux store must mean there is an issue when matching the query with the requested fields.
Possible fix: https://github.com/apollostack/apollo-client/pull/629
I think this is fixed now.
I'd like to re-open this issue (as opposed to creating a new one).
We're running apollo-client 0.8.1 and still seeing this issue.
It looks like PR #629 (which is really PR #669) may have been regressed.
Here's a similar query to the one that's causing the issue:
query StudentQuery($schoolId:ID!, $classId:ID!, $studentId:ID!) {
school: schoolById(id: $schoolId) {
id
class: studentById(classId: $classId, studentId: $studentId) {
... on ScienceMajor {
...UserFragment
info {
updatedAt
createdAt
}
}
}
}
}
fragment UserFragment on ScienceMajor {
info {
id
firstName
lastName
}
}
Only the updatedAt and createdAt fields are being sent to props - not the fields in the fragment.
I鈥檝e been working on refactoring the store and I noticed our implementation of field merging was incorrect (forgot to mention that to @helfer 馃槉). We only seem to merge for fragments even though technically any field can be merged in GraphQL (take for instance { foo { a bar { x y } } foo { b c bar { z } } }). I noticed that our array field merging may also be broken in a similar way.
This issue will be fixed in the future as we get closer to 1.0. In the meantime I think the following should work as a workaround:
{
...UserFragment
... {
info {
updatedAt
createdAt
}
}
}
Note how I wrapped info { updatedAt createdAt } in a fragment without a type condition. This should fool Apollo into running its fragment merging logic. Let me know if this workaround works for you 馃憤
@calebmer Thanks for the response. I tried your temporary hack, but was getting an undefined error. I just created a temporary fragment and that worked perfectly:
{
...UserFragment
...TemporaryFragment
}
fragment TemporaryFragment on ScienceMajor {
info {
updatedAt
createdAt
}
}
@calebmer, is there another issue that we can follow to track your progress towards a holistic fix?
I'm still experiencing this problem and the typeless, anonymous fragment isn't working as a workaround.
I think this has been fixed with #1483. If not, please open a new issue!