question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

converting `null` to `undefined`

See original GitHub issue

Intended outcome:

In Apollo 2, I’m trying to convert all null values to undefined in every query response.

Actual outcome:

I get a console warning saying the field is missing. It looks like:

writeToStore.js:114 Missing field locationType in {
  "__typename": "Offense",
  "id": "77205221-5f74-45b9-5268-67f96b55beb4",
  "kind": "INTIMIDATION"

I also get no response back and no errors

How to reproduce the issue:

This is how I define my link:

const httpLink = createHttpLink({
  uri: window.xnGlobals.ENDPOINT_GQL,
  fetch,
})
const nullToUndefined = value => {
  if (isPlainObject(value)) {
    return mapValues(value, nullToUndefined)
  }
  if (isArray(value)) {
    return value.map(nullToUndefined)
  }
  if (value === null) {
    return undefined // THIS SHOULD BE UNDEFINED
  }
  return value
}
const nullLink = new ApolloLink((operation, forward) => forward(operation).map(nullToUndefined))
const link = nullLink.concat(httpLink)

Version

  • apollo-client@2.0.0

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:10
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

25reactions
jtomaszewskicommented, Jan 6, 2021

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 nulls with undefineds? For TS devs, the difference between null and undefined is meaningless, and that’s why most of TS devs have dropped the null type completely.

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;
}
9reactions
obartracommented, Oct 28, 2017

I’m trying to simplify how I handle default values. undefined is used for ES6 default parameters, React default props and applying defaults in other libraries like lodash. So it’s a more convenient way to indicate a value has not been set for me. Otherwise I need to manually check and apply default values.

I assumed link allowed me to modify a response after it was processed by apollo-client (so that apollo client would use null/undefined internally the same way). Maybe I’m using the wrong method? Is there another hook to modify the response without affecting the library?

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 hasOwnProperty or 'key' in object instead?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a JavaScript idiom to change "undefined" to "null"?
I'm not sure if there's a nice quick way to convert between them, but if it helps: undefined == null returns true, unlike...
Read more >
null-as-undefined - npm
Convert `null` values to `undefined` in a way that TypeScript understands. Latest version: 0.4.0, last published: a year ago.
Read more >
Null Vs Undefined in TypeScript - TekTutorialsHub
TypeScript has two special values for Null and Undefined. Both represent no value or absence of any value. The difference between Null ......
Read more >
null - JavaScript - MDN Web Docs - Mozilla
When checking for null or undefined , beware of the differences between equality (==) and identity (===) operators, as the former performs type-conversion....
Read more >
Null and undefined (Reference) - Prisma
Use case: null and undefined in a GraphQL resolver ... // Update author's email or name, or both - or neither! updateUser(id: Int!,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found