Bartosz
Bartosz

Reputation: 1594

Check if given type has a property named X. Reduce inline fragments

I have a query that fetches some events array. Each node inside of edges can implement on of finite number of interfaces.

Question: Is it possible to check if a given node has a property named X (in this case id, timestamp and content) instead of using multiple inline fragments (... on {Type})?

        events(last: $eventCount) {
            edges {
                node {
                    ... on Type1 {
                        id
                        timestamp
                        content
                    }
                    ... on Type2 {
                        id
                        timestamp
                        content
                    }
                    ... on Type3 {
                        id
                        timestamp
                        content
                    }
                    ... on Type4 {
                        id
                        timestamp
                        content
                    }
                }
            }
        }

In this example I'd like to get rid of ... on Type1, ... on Type2 etc. and just check if id, timestamp and content properties exist.

Upvotes: 0

Views: 26

Answers (1)

Phil Plückthun
Phil Plückthun

Reputation: 1439

There are two answers here depending on what you're trying to achieve, but the short answer is no: You can't conditionally spread a fragment based on the value you're reading.

However, what you can do is check the interface itself. You mentioned that these nodes all implement interfaces. So I'm assuming these nodes are either all implementing a common interface and nodes itself is either listing out an interface or a union of multiple types.

If you ensure that all your types, TypeN, are implementing an interface that includes the fields you're trying to check for then you can simply spread a fragment on this interface:

interface BaseType {
  id: ID!
  timestamp: DateTime
  content: String
}

type TypeA implements BaseType {
  id: ID!
  timestamp: DateTime
  content: String
  # ...
}

Given this interface you can then query for every type implementing this interface:

{
  ... on BaseType { id timestamp content }
}

This will work even if you don't include all fields. I assume that content for instance may have a varying type, which means that you can't query it across all types at once.

Upvotes: 1

Related Questions