How to deal with nulls in GraphQL schema - graphql

I keep getting the "Cannot return null for non-nullable field Airline.id." error when FlightSchedule.operatingAirline is null (perfectly valid as per schema) and client queries for FlightSchedule.operatingAirline.id. How to fix this? Making Airline.id, Airline.code and Airline.name as nullable fixes this but is not the right way to solve this problem because if an Airline exist, these 3 fields will always exist too. Below is my schema:
type Airline {
id: String!,
code: String!,
name: String!
}
type FlightSchedule {
airline: Airline!
operatingAirline: Airline
}
And below is my query:
getFlightSchedules {
airline
{
id
code
name
}
operatingAirline
{
id
code
name
}
}

A field will resolve to null when an error is encountered while resolving it. This includes validation errors like the one you're encountering. From the spec:
If during ExecuteSelectionSet() a field with a non‐null fieldType throws a field error then that error must propagate to this entire selection set, either resolving to null if allowed or further propagated to a parent field.
If this occurs, any sibling fields which have not yet executed or have not yet yielded a value may be cancelled to avoid unnecessary work.
In other words, if a parent field is of a particular object type, and that type has a non-nullable field, and that field resolves to null, that parent field will also resolve to null. The parent field cannot return an object that is invalid (in this case because it had a non-null field return null), so the only thing it can do is return null. Of course, if the parent field itself is non-null, this behavior is propagated up the tree until a nullable field is finally encountered.
So, why are you getting that error? Because your resolver for operatingAirline is not returning null. It is returning some kind of object (either an incomplete airline object, an array, a string or something else) that GraphQL then effectively tries to coerce into the Airline type. The id field was requested, but it resolves to null based on the object returned by operatingAirline's resolver. Since the id was requested and returned null, the entire operatingAirline field fails validation and returns null.

Related

GraphQL: No child/nested data available in response when parent is null?

I am facing problems with nullable fields when trying to use the data returned when executing my query.
Schema
A simplified schema for demonstration purpose:
type Query {
members: [Instrument!]!
}
type Instrument {
series: SeriesType!
...
}
type SeriesType {
dividendYield: SeriesMethods
...
}
type SeriesMethods{
latest: Float!
...
}
There is nullable data that is resolved at dividendYield and a typical response I get when executing the query is shown in the following section.
Typical Response
A picture of the query and response can be seen here.
So what is the problem???
We are using this data to for visuals on a web app. The data is read in as an object such that you are able to access the data by data.series.dividendYield.latest. The problem comes in when dividendYield returns null as there is there no longer exists a latest field anymore.
For the client side it will always be necessary for the field to be present in the data, even if the parent resolver is null. Is it possible for the resolvers to be setup such that all children fields also return null rather than not appearing in the data response? Any other solutions would also be appreciated.

GraphQL non-nullable field nested in nullable field

I have a GraphQL query that returns a set of notifications. The "creator" field does not appear in every notification which is a problem because it is of type "User" and User has an "id" field that is non-nullible. Is it possible to have non-nullible fields nested in nullable ones?
{
myNotifications {
id
title
message
image
creator {
id
full_name
}
}
}
A non-null field will only be validated if it is resolved. If the parent field resolve to null, any children fields will not be resolved, and so the validation never happens. In other words, it's perfectly fine to have a non-null field whose parent field is nullable.

GraphQL not null field of nullable object returning error

The following schema contains not null field in an object that is optional (the entire object is allowed to be null).
It defines a list of Parent objects that have optional field Child - some Parents are allowed to have null Child.
type People {
people : [Parent]
}
type Parent {
child : Child
}
type Child {
key : String!
}
The following GraphQL query returns an expected list of Parent objects (some with null Child values).
But it also returns an error attached to the result.
Is this a bug in GraphQL (Child is optional)? Or is it expected behaviour?
Cannot return null for non-nullable type: 'String' within parent 'Child'
This is expected behavior. The issue is not that some child field is null, but that some Child is returning null for key -- that's the String that's referred to in the error. You won't see the null key in your data; instead, the offending child field will just return null instead. That's because GraphQL errors are "bubbled up" to the next nullable parent field, as described in the spec:
Since Non-Null type fields cannot be null, field errors are propagated to be handled by the parent field. If the parent field may be null then it resolves to null, otherwise if it is a Non-Null type, the field error is further propagated to it’s parent field.

Error on GraphQL : no provided id but the store already contains an id of

I am very new to GraphQL and Apollo, and I don't understand what is wrong with the 'aliasEmail' field below. When I add this one to the query, I get this error message. When I remove it from the query, everything works perfectly.
It is well defined in 'types.graphql' and is just a simple string field.
index.js:2178 Unhandled (in react apollo:Apollo(withRouter(EmailSettingsContainer))) Error: Network
error: Error writing result to store for query:
query getCompanyForAliasEmailEditForm($companyId: ID) {
Company(id: $companyId) {
name
isTaxActive
telFixe
aliasEmail
telMobile
__typename
}
}
Store error: the application attempted to write an object with no
provided id but the store already contains an id of
Company:cje6xkcnxl83u01353a20p1t6 for this object. The selectionSet
that was trying to be written is:
Company(id: $companyId) {
name
isTaxActive
telFixe
aliasEmail
telMobile
__typename
}
It sounds like there's already another query being made elsewhere in the app that also returns the Company object and that query includes the id (or _id) field, while the query in this case does not. Apollo uses both the typename and id to generate the cache key for your query result (unless dataIdFromObject is used to modify this behavior), and so throws an error when it detects the above discrepancy. Try including the id field in your getCompanyForAliasEmailEditForm query.

How to return an object or null in GraphQL?

I have the following schema:
type User {
email: String!,
user_id: String!,
img: String!,
},
type Query {
getUser(user_id: String!): User
}
The schema reflects the fact that I must return an User object. However, I can not always do this, and sometimes I need to return null. For example, if I make a request to the DB, it will return return object or null (if the user was not found).
In my GraphQL schema, I set the type for a particular field. If I try to return a different type than what I set, I get an error. How do I allow a field to return either an object or null?
According to the spec:
By default, all types in GraphQL are nullable; the null value is a valid response for all of the above types. To declare a type that disallows null, the GraphQL Non‐Null type can be used.
In other words, types in GraphQL are nullable by default. So a field like
getUser: User
may return either a User object or null. A field like
name: String
may return either a String or null. Only by explicitly specifying a field as non-null (in SDL, by appending a ! to the type), can we specify that a field should never return null. For example:
name: String!
It's also important to note that the Promise returned in your resolver must resolve to either null or undefined in order to be coerced into a null value. In other words, if you return an empty object ({}), an empty array ([]) or some other value, GraphQL will treat this as you returning an object and not a null value!
In your schema, the email field on User is String!, meaning it cannot resolve to null. If you run a query like
query {
getUser(user_id: "1") {
email
}
}
and the resolver for getUser returns an empty object ({}), GraphQL will attempt to resolve email, return null for it and blow up because email is not supposed to be null! If, however, getUser resolves to null, none of the child fields will be resolved and you will not get any error.
According to Graphql - get full sub-object, or null if doesn't exist, you get the error you describe when you return empty object (i.e. {}) instead of null from your GraphQL function.
I had similar problem: I kept getting the "error: lack the require field" error in GraphQL response until I made sure I was actually returning null, not empty object.

Resources