I want to render two same tables in the same page with some different variables. I expected it should be
graphql.experimental`
fragment xxx_viewer on Viewer @argumentDefinitions(
true: {type: "Boolean", defaultValue: true},
false: {type: "Boolean", defaultValue: false}
) {
ASource: ...table_viewer @arguments(fromA: $true)
BSource: ...table_viewer @arguments(fromB: $true)
}
`
But it returned an error: GraphQLError: Syntax Error xxx.js (7:23) Expected Name, found .... How can I do something like this except separated two fragments.
you don't need to alias fragments, just pass viewer to Table component and it will work fine
@sibelius Thanks for the reply.
Since the table needs to implement pagination, I expected that should be handled by Table component instead of the parent component. And I have a page need to display the table twice with different arguments, so I think I need to use the alias fragments. Or there are the other ways to do this?
I want to render something like this.
render() {
return (
<div>
<Table fromSourceA={true} viewer={this.props.viewer} />
<Table fromSourceB={true} viewer={this.props.viewer} />
</div>
)
}
And the table needs pagination.
I'm having almost the same problem.
owners: ...RelationFragment @arguments(types: $ownerTypes)
members: ...RelationFragment @arguments(types: $membersTypes)
But I think it's not a problem related to Relay but GraphQL doesn't let us to do that.
@ErrorPro Oh... so what is your current solution??
@ericsin112 I see only one solution now for my case smth like this:
compose(
queryRenderer(graphql`
query CompanyContainerQuery {
Company {
name
owners: relations(types: [OWNER]) {
edges {
node {
...RelationUsersListContainer
}
}
}
members: relations(types: [MEMBERS]) {
edges {
node {
...RelationUsersListContainer
}
}
}
}
}
`),
mapProps(props => ({
...props,
owners: props.Company && props.Company.owners.edges
.map(e => <RelationUsersListContainer data={e} />),
members: props.Company && props.Company.members.edges
.map(e => <RelationUsersListContainer data={e} />),
})),
)(Company)
In your case it would be the same, just use aliases in parent query
@ErrorPro But how did you implement pagination ($first, $after)?
I didn't because I didn't need it. But I don't see any problem to use what I mentioned about inside refetch fragment.
{
feed: graphql.experimental`
fragment FeedStories_feed on Feed
@argumentDefinitions(
count: {type: "Int", defaultValue: 10}
) {
firstTable: stories(first: $count, isTrue: $true) {
edges {
node {
id
...Story_story
}
}
}
secondTable: stories(first: $count, isTrue: $true) {
edges {
node {
id
...Story_story
}
}
}
}
`
}
@ErrorPro If I clicked the next page on firstTable, both tables will update, but I just want to update the firstTable.
I have not tested it but you maybe able to create multiple containers reusing the same component.
@mmjd Thanks. This is my current solution and I just want to find out whether there is a better way to do that. In this solution, I need to update both fragments whenever either one updated, I don't think it is a good solution.
@ericsin112 It happens because you use the same variable for both tables. Use different variables for different tables e.g. firstCount, secondCount. Then it should work
I'm sorry this issue has sat here for so long. In an attempt to clean up our issue queue we're closing some aging or unclear-action issues.
Sounds like some answers were achieved here. The original post did not contain valid graphql syntax while the suggested fix does.
@leebyron I've got this error when I try to spread same fragment with different props
RelayFragmentPointer: Expected an array with at most one set of variables per concrete fragment, got [object Object],[object Object]
example:
...table_viewer @arguments(isActive: $true)
...table_viewer @arguments(isActive: $false)
how can we handle this case?
What would you expect the response to look like in this case?
{
"data": {
"parent_field": {
"table_viewer": "isActive true data",
"table_viewer": "isActive false data"
}
}
}
Evidently that's not valid. You need aliases so that the data can be returned under two different keys, but GraphQL itself doesn't allow you to alias fragments (fragments aren't visible in response, only their contents are: the selections in the fragment are returned inline in the response; there is no key in the response that corresponds to the fragment and could be aliased).
The workaround here is to alias the parent field containing the fragment spread, which will work because fields can be aliased in GraphQL.
... SomeFragment on Thing {
active_parent_field: parent_field {
...table_viewer @arguments(isActive: $true)
}
inactive_parent_field: parent_field {
...table_viewer @arguments(isActive: $false)
}
}
Most helpful comment
What would you expect the response to look like in this case?
Evidently that's not valid. You need aliases so that the data can be returned under two different keys, but GraphQL itself doesn't allow you to alias fragments (fragments aren't visible in response, only their contents are: the selections in the fragment are returned inline in the response; there is no key in the response that corresponds to the fragment and could be aliased).
The workaround here is to alias the parent field containing the fragment spread, which will work because fields can be aliased in GraphQL.