graphql
graphql copied to clipboard
Cannot read property 'name' of undefined when querying interfaces
Is your feature request related to a problem? Please describe.
As implemented in v3, interfaces have a limited where filtering capability compared to unions. This is because the InterfaceWhere
that is generated only contains the interface properties and not the properties of implementers. If this is intentional, then I open this ticket as a feature request. If unintentional, then consider this a good repro. If this DOES work and i'm missing it, then consider this a documentation suggestion 🤣
Note I also scanned through the existing Interface bugs, and saw several maybe related issues but nothing stood out as the same issue or containing the same level of clarity in the example:
Schema
type food {
name: String
ingredients_interface: [Ingredient_Interface!]! @relationship(type: "has_Ingredient_Interface", direction: OUT)
ingredients_union: [Ingredient_Union!]! @relationship(type: "has_Ingredient_Union", direction: OUT)
}
interface Ingredient_Interface {
id: ID! @id(autogenerate: true)
name: String
}
type Banana implements Ingredient_Interface {
id: ID! @id(autogenerate: true)
name: String
sweetness: String
qty_ozs: Float
}
union Ingredient_Union = Sugar | Syrup
type Sugar {
id: ID! @id(autogenerate: true)
name: String
sweetness: String
qty_ozs: Float
}
type Syrup {
id: ID! @id(autogenerate: true)
name: String
sweetness: String
qty_ozs: Float
}
Seed some data
mutation {
createFoods(
input: [
{
name: "Cake"
ingredients_interface: {
create: [
{ node: { Banana: { name: "Golden Banana", qty_ozs: 100 } } }
]
}
ingredients_union: {
Sugar: {
create: [
{ node: { name: "Simple Sugar", qty_ozs: 100 } }
{ node: { name: "Brown Sugar", qty_ozs: 10 } }
]
}
Syrup: { create: { node: { name: "Maple Syrup", qty_ozs: 100 } } }
}
}
]
) {
foods {
name
}
}
}
Query showing limitations of interface where
{
foods(where:{
ingredients_unionConnection_ALL:{
Sugar:{
node:{
qty_ozs_GT: 1
}
}
}
ingredients_interfaceConnection_ALL:{
node:{
# qty_ozs_GT not available here
# only interfacfe level fields on where
# in this example name and id
}
# Banana not available here like with unionWhere
}
}) {
name
}
}
Describe the solution you'd like In the above example, I'd expect to be able to filter on interfaces like I do on unions. For example adding a query something like this:
Banana :{
node:{
qty_ozs_GT: 1
}
}
In practice this would make interfaces MUCH more useful when querying data.
Describe alternatives you've considered
None
Additional context
Versions:
"@neo4j/graphql": "3.0.1", "@neo4j/graphql-ogm": "3.0.1", Neo4j: 4.3.2
@cramatt You will only get the interface fields at that level in the where input. There exists a special key _on
that allows for access to the fields on the implementations. In other words, if you wanted to do something like your example you would need:
{
foods(where:{
ingredients_interfaceConnection_ALL:{
node:{
_on: {
Banana: {
qty_ozs_GT: 1
}
}
}
}
}) {
name
}
}
This has implications for fetching the data and overriding shared fields.
This is documented here: https://neo4j.com/docs/graphql-manual/current/type-definitions/interfaces/#type-definitions-interfaced-types-querying
@dmoree ah, ok, so its supported (although in a different way than unions) and I missed it in the docs - thanks for pointing me in the right direction.
However now I'm running into another issue...
I can followup with a more detail repro, but off the bat I'm getting an error trying to run the query you provided. Maybe this is related to one of the known issues??
Heres a screenshot showing the data has the name property:

But running this query
{
foods(
where: {
ingredients_interfaceConnection_ALL: {
node: { _on: { Banana: { qty_ozs_GT: 1 } } }
}
}
) {
name
ingredients_interface {
name
... on Banana {
qty_ozs
}
}
}
}
Results in this error:
{
"errors": [
{
"message": "Cannot read property 'name' of undefined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"foods"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Cannot read property 'name' of undefined",
" at /website/node_modules/@neo4j/graphql/src/translate/where/create-where-and-params.ts:189:55",
" at Array.forEach (<anonymous>)",
" at reducer (/website/node_modules/@neo4j/graphql/src/translate/where/create-where-and-params.ts:183:41)",
" at Array.reduce (<anonymous>)",
" at createWhereAndParams (/website/node_modules/@neo4j/graphql/src/translate/where/create-where-and-params.ts:264:60)",
" at translateTopLevelMatch (/website/node_modules/@neo4j/graphql/src/translate/translate-top-level-match.ts:92:43)",
" at translateRead (/website/node_modules/@neo4j/graphql/src/translate/translate-read.ts:51:49)",
" at resolve (/website/node_modules/@neo4j/graphql/src/schema/resolvers/read.ts:31:47)",
" at Object.foods (/website/node_modules/@neo4j/graphql/src/schema/resolvers/wrapper.ts:98:16)",
" at field.resolve (/website/node_modules/apollo-server-core/src/utils/schemaInstrumentation.ts:106:18)"
]
}
}
}
],
"data": null
}
Thoughts?
Maybe related to https://github.com/neo4j/graphql/issues/1049 ?
No more errors encountered here for this bug, so this can be considered fixed in the latest release! Sorry for the slow updates, this may have been fixed for a while through some major refactors that we've done and we just haven't reconfirmed.