Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Optional input is set to null #1569

Closed
jurajkrivda opened this issue Jan 22, 2018 · 11 comments · Fixed by #3056
Closed

Optional input is set to null #1569

jurajkrivda opened this issue Jan 22, 2018 · 11 comments · Fixed by #3056

Comments

@jurajkrivda
Copy link

jurajkrivda commented Jan 22, 2018

Hello. I have a "users" request with userFilterInput which is optional. In my case i do not set the filter. Apollo will send this request to the server

{"operationName":"users","variables":{"userFilterInput":null},"query":"query users($userFilterInput: UserFilterInput) {\n  users(userFilterInput: $userFilterInput) {\n    id\n    email\n    lastName\n    firstName\n    __typename\n  }\n}\n"}

Why userFilterInput is set to null and not to undefined? Bellow you can find my code and you can see that I did not set up any filter.

export const USERS = gql`
  query users($userFilterInput: UserFilterInput) {
    users(userFilterInput: $userFilterInput) {
      id
      email
      lastName
      firstName
    }
  }
`;

export default graphql(USERS, {
  options: () => ({
    notifyOnNetworkStatusChange: true,
  }),
  props: ({ data: { loading, error, users, networkStatus, refetch } }) => ({
    usersLoading: loading,
    usersError: error,
    usersRefetch: refetch,
    users,
    networkStatus,
  }),
});
@jurajkrivda jurajkrivda changed the title I Optional input set to null Jan 22, 2018
@jurajkrivda jurajkrivda changed the title Optional input set to null Optional input is set to null Jan 22, 2018
@dacz
Copy link

dacz commented Jan 23, 2018

I agree with @jurajkrivda .

Nullable input when not presented within the query variables in apollo client, is getting called with null value.

Client should not pass the whole input as null, it should omit it completely or pass it with undefined.

Passing null may mean explicitly null the input. Same applied to input fields, so the server may react on explicitly resetting the value (presented in the input with null or do not handle it if omitted). As discussed apollographql/apollo-kotlin#652 or apollographql/apollo-tooling#81

@menkveldj
Copy link

I have a similar problem. I was able to solve it with a utility function that passes only into the request variables:

utils.js

// handle empty string
export const graphqlFriendlyObject = x => Object.keys(x).reduce((p, c) => {
  p[c] = x[c] || undefined;
  return p;
}, {});

And then in my mutation:

import {graphqlFriendlyObject} from "../../Utils";
...
graphql(MutationUpdateChild, {
    options: {
      refetchQueries: [{ query: QueryAllChildren }],
      update: (proxy, { data: { updateChild } }) => {
        const query = QueryAllChildren;
        const data = proxy.readQuery({ query });

        // find item to update
        const updateIndex = data.listChildren.items.findIndex(
          child => child.id === updateChild.id
        );

        // splice in update
        data.listChildren.items.splice(updateIndex, 1, updateChild);
        proxy.writeQuery({ query, data });
      }
    },
    props: props => ({
      updateChild: child => {
        const fChild = graphqlFriendlyObject(child);

        return props.mutate({
          variables: { ...fChild, expectedVersion: fChild.version },
          optimisticResponse: () => ({
            updateChild: {
              ...child,
              __typename: "Child"
            }
          })
        });
      }
    })
  }),

@strblr
Copy link

strblr commented Dec 1, 2018

Something new on this ?

I recently upgraded my package.json configuration (for a professional project) and it led to a huge backward incompatibility. I used to handle "null" as an explicit value ("set this field to null in the database") and undefined as a way to tell the server there's nothing to change, it's just an optional parameter that was omitted. My fix was just to force the install of an earlier version of the apollo server.

By setting optional parameters to null, how do you even make the difference between omitted optional parameters and the actual value "null" ?

@kruncher
Copy link

We're having the same issue, any thoughts ?

@zamiang
Copy link

zamiang commented Jan 25, 2019

Same - we check every version against our test suite and have not been able to update past react-apollo 2.1.11 due to this issue. I believe that is the newest version that correctly implements the graphql spec as @dacz mentioned above.

@zamiang
Copy link

zamiang commented Jan 31, 2019

Tested with 2.4.1 and 2.5.0 beta and issue still persists (is easy to repro with the the info in the issue description). Would love to know if this is intended behavior or not.

@JBustin
Copy link

JBustin commented Feb 27, 2019

Same, very boring !!
Thx @zamiang to check for every new version ;)

@brandonferrer
Copy link

brandonferrer commented Mar 12, 2019

Same issue, would love an update!

Playing with a gross workaround until something more elegant is suggested. In this example, I'm trying to rehydrate my client cache with some remote data. With all of these fields being optional, if no remote data exist, I'm calling the mutation without some variables and it's setting them to null. In your writeQuery data, you can have some ternary logic to handle default values or set as undefined.

export const rehydrateDetailsCache = (
  _obj,
  {
    flyerTitle,
    participationFee,
    eventLocation,
    registrationDeadlineRequired,
    deadlineDate,
  },
  { cache }
) => {
  cache.writeQuery({
    query: DETAILS_QUERY,
    data: {
      campaignDetails: {
        __typename: 'CampaignDetails',
        flyerTitle,
        participationFee,
        eventLocation,
        registrationDeadlineRequired: registrationDeadlineRequired
          ? registrationDeadlineRequired
          : true,
        deadlineDate: deadlineDate ? deadlineDate : undefined,
      },
    },
  });
  return null;
};

@strblr
Copy link

strblr commented Mar 12, 2019

This is now an issue for more than a year. Several threads were opened about it on Github. Still nothing changed. We didn't even get a proper explanation.

This was a major break in regards to backward compatibility and a lot of people are concerned with this.

Can we get an answer, please ?

@SerhiiChepur
Copy link

SerhiiChepur commented Mar 15, 2019

@jurajkrivda have you tried to use the default scalar ID? type as workaround?

@amwill04
Copy link

Setting optional inputs to null also breaks the default value set on an apollo server - seems rather counter intuitive.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants