-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
converting null
to undefined
#2412
Comments
hmm @obartra I do believe that we treat undefined as bad responses (missing fields) since the GraphQL spec only allows for returning nulls in the case of empty data. What is your use case? |
I'm trying to simplify how I handle default values. I assumed If that's not available, I'm not familiar with the implementation details, but would it be possible to detect if a field is present with |
@obartra I think we can probably make those adjustments! The first step would be to write a failing test showing how |
For sure, how do you want to approach it? Do you want me to add tests for supporting this I don't see many tests for |
Hey @jbaxleyiii, not to nag you but if you can give me some direction on the issues ^ I can get started with some test cases |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client! |
My current approach is to do the following: const nullToUndefined = value => {
if (_.isPlainObject(value)) {
return _.mapValues(value, nullToUndefined)
}
if (_.isArray(value)) {
return value.map(nullToUndefined)
}
if (value === null) {
return undefined
}
return value
}
const internal = new ApolloClient({ /* ... */ })
export const client = {
...internal,
mutate: (...args) => internal.mutate(...args).then(nullToUndefined),
query: (...args) => internal.query(...args).then(nullToUndefined),
} It seems to do the trick but it's far from a clean solution |
I have a similar problem. I was able to solve it with a utility function that passes only into the request variables: utils.js
And then in my mutation:
|
Any news on this front? Looking at wanting this behavior too but can't find a good way to implement it across the whole client for consistent behaviour. @obartra solution doesnt work with |
If the issue is with the export function Query<R: {}>({ children, ...props }: Props<R>) {
return (
<ReactApolloQuery fetchPolicy="cache-and-network" {...props}>
{(response: any = {}) => children(((nullToUndefined(response): any): R))}
</ReactApolloQuery>
)
} But all these are just hacky workarounds. It would be nice to be able to modify the responses of all queries and mutations directly from Apollo middleware |
Yeah that would be ideal, even the ability to allow partial matches to return responses would allow the link solution to work. |
I get your fix with the function @obartra and it helped a lot. But how you solve this with the graphql hoc ? Are you doing a simple props() override or something before this ? |
@jbaxleyiii Hi can you point out where is the code ("treat undefined as bad responses") is? I encountered a similar problem because of the server-side program ( |
Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. If this is still a problem (using a modern version of Apollo Client), please let us know. Thanks! |
Is there a thread somewhere on Apollo in which you discuss whether you'd be willing to support adding an option to the apollo server/client, that would replace all Without that, currently we're forced to either use nulls (just because GQL client/server uses them), or use helpers like this one: type RecursivelyReplaceNullWithUndefined<T> = T extends null
? undefined // Note: Add interfaces here of all GraphQL scalars that will be transformed into an object
: T extends Date
? T
: {
[K in keyof T]: T[K] extends (infer U)[]
? RecursivelyReplaceNullWithUndefined<U>[]
: RecursivelyReplaceNullWithUndefined<T[K]>;
};
/**
* Recursively replaces all nulls with undefineds.
* Skips object classes (that have a `.__proto__.constructor`).
*
* Unfortunately, until https://github.com/apollographql/apollo-client/issues/2412
* gets solved at some point,
* this is the only workaround to prevent `null`s going into the codebase,
* if it's connected to a Apollo server/client.
*/
export function replaceNullsWithUndefineds<T>(
obj: T
): RecursivelyReplaceNullWithUndefined<T> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const newObj: any = {};
Object.keys(obj).forEach((k) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const v: any = (obj as any)[k];
newObj[k as keyof T] =
v === null
? undefined
: // eslint-disable-next-line no-proto
v && typeof v === "object" && v.__proto__.constructor === Object
? replaceNullsWithUndefineds(v)
: v;
});
return newObj;
} |
期待这个问题能被正确的解决 |
Is there a generally accepted answer to this? It's quite annoying to have to deal with this on the client side when using Typescript. Reading through the thread it seems like this should still be open. |
It's actually very annoying. In typescript an optional field is defined as |
Intended outcome:
In Apollo 2, I'm trying to convert all
null
values toundefined
in every query response.Actual outcome:
I get a console warning saying the field is missing. It looks like:
I also get no response back and no errors
How to reproduce the issue:
This is how I define my
link
:Version
The text was updated successfully, but these errors were encountered: