Hi @helfer @stubailo ,
I just found out how to implement a Resolver for a single Union (#172), but how about resolving a list of Unions?
In relation to the example provided in #172: how would I resolve a list of Characters? ([Character]!)
For me this is a practical issue. I am using this in a real-life case with an AvailableSearchFilters Union List, which can contain for example a GeoPointDistanceFilter and a PriceRangeFilter.
Of course I'm willing to update the docs if you can point me to the solution.
Kind regards,
Sander
Just return a list where each item implements one of the union types. Or return a list of promises that resolve to one of those types. I believe the resolveType method will still apply to each individual item, but if that doesn't work, you can try defining ofType on each of the implementing types.
Hi @helfer,
Thanks for pointing that out.
I got it to work with a list of interfaces using __resolveType, but not with the list of unions.
I cannot find any documentation on ofType. Can you give me an example, or point me to the documentation?
Kind regards,
Sander
Edit: using "graphql": "^0.7.2", "graphql-tools": "^0.7.2"
Addendum
So when resolving a list of NodeInterfaces, this works:
NodeInterface: {
__resolveType(root:Object, context:Object, info:Object) {
if(root._graphQLType === 'Offer'){
return 'Offer';
}
return null;
},
},
But when resolving a list of SearchFilterUnions, the specific resolver isn't called. The array is available on the parent resolver though.
SearchFilterUnion: {
__resolveType(root:Object, context:Object, info:Object) {
console.log('\n\nSEARCHFILTERUNION: ', root) // TODO remove
if( root.offerCategoryFilter) {
return 'OfferCategorySearchFilter'
}
if( root.geoBoundingBoxFilter) {
return 'GeoBoundingBoxSearchFilter'
}
if( root.geoDistanceFilter) {
return 'GeoDistanceSearchFilter'
}
if( root.priceRangeFilter) {
return 'PriceRangeSearchFilter'
}
return null
}
},
Example array logged from parent:
[ offerCategoryFilter: { id: '6ca46120-8a42-11e6-8692-553a5a80fc35' },
geoBoundingBoxFilter: { topLeft: { lat: 86.5, lon: 86.5 },
bottomRight: { lat: 5.5, lon: 5.5 } },
geoDistanceFilter: { location: { lat: 5.5, lon: 5.5 },
distance: 15000,
units: 'km' },
priceRangeFilter: { min: 6, max: 44 } ]
Any clue?
Phew... I've found the issue.
Do not name array elements like this, as _named array elements seem not to be passed to the resolver_:
// WRONG!
[ offerCategoryFilter: { id: '6ca46120-8a42-11e6-8692-553a5a80fc35' },
geoBoundingBoxFilter: { topLeft: { lat: 86.5, lon: 86.5 },
bottomRight: { lat: 5.5, lon: 5.5 } },
geoDistanceFilter: { location: { lat: 5.5, lon: 5.5 },
distance: 15000,
units: 'km' },
priceRangeFilter: { min: 6, max: 44 } ]
// END-WRONG!
Instead, use a default array like this, you can pass the ofType to resolve the Union type:
[ { id: '6ca46120-8a42-11e6-8692-553a5a80fc35',
ofType: 'offerCategoryFilter' },
{ topLeft: { lat: 86.5, lon: 86.5 },
bottomRight: { lat: 5.5, lon: 5.5 },
ofType: 'geoBoundingBoxFilter' },
{ location: { lat: 5.5, lon: 5.5 },
distance: 15000,
units: 'km',
ofType: 'geoDistanceFilter' },
{ min: 6, max: 44, ofType: 'priceRangeFilter' } ]
Now you can resolve the union type like this:
SearchFilterUnion: {
__resolveType(root:Object, context:Object, info:Object) {
if( root.ofType === 'offerCategoryFilter') {
return 'OfferCategorySearchFilter'
}
if( root.ofType === 'geoBoundingBoxFilter') {
return 'GeoBoundingBoxSearchFilter'
}
if( root.ofType === 'geoDistanceFilter') {
return 'GeoDistanceSearchFilter'
}
if( root.ofType === 'priceRangeFilter') {
return 'PriceRangeSearchFilter'
}
return null
}
},
I was surprised the resolver skips named array elements. Is this intended behaviour? Took me a while to figure this out :)
@sandervanhooft that sounds like something that would need to be fixed in GraphQL.js - this package doesn't deal with execution at all. However, if you have some ideas for where documentation could be improved, please file an issue here: https://github.com/apollostack/tools-docs
Most helpful comment
Phew... I've found the issue.
Do not name array elements like this, as _named array elements seem not to be passed to the resolver_:
Instead, use a default array like this, you can pass the
ofTypeto resolve the Union type:Now you can resolve the union type like this: