Repository: apollographql/apollo-client

Problem statement:
Query result not delivered to component if array contains null values
I have an issue where my query works in Graphiql in my browser, but wont work for me in my React Native app.

This is a condensed version of the query:
```  query getTeam($teamId: String!, $gameweek: Int!) {
    team(_id: $teamId) {
      _id
      history {
        score
      }
    }
```
If I don’t request `history` it works for me in RN too. When I do request `history` I don't get any data back from the server for team. The server is getting the request and sending back data from my server console logs.

And the definition of team (condensed) is:
```
type Team {
  _id: ID
  history: [FixtureHistory]
}

type FixtureHistory {
  lineup: [String]
  subs: [String]
  score: Int
  finalLineup: [String]
  finalSubs: [String]
  autoSubs: [AutoSub]
  players: [Player]
}
```

Any idea why this works fine in Graphiql but not with Apollo Client on React Native?


Hints:
Here's a gist of the code: https://gist.github.com/elie222/cb1b594e3b91f7d860454c5a9594823e
What do you mean by "doesn't work"? Does it simply silently fail? What props does your component receive, if any? Are any errors or warnings printed?
This is the result I receive when I request `history`:

<img width="177" alt="screen shot 2017-04-05 at 23 30 42" src="https://cloud.githubusercontent.com/assets/3090527/24749043/4d944222-1aca-11e7-96a6-3fcea4a7e5be.png">

When I don't request `history` I receive all the props as expected (`team`, `players`, ...).

And the request always works fine with graphiql.
This is the graphiql query (and works fine):
```
query getTeam($teamId: String!) {
    team(_id: $teamId) {
      _id
      name
      userId
    	playerIds
      history {
        lineup
  	  	subs
    		score
    		finalLineup
    		finalSubs
  			autoSubs {
  			  in
  			  out
  			}
      }
    }
}
```

And the result:
```
{
  "data": {
    "team": {
      "_id": "2rMRFYpdeeDBLT825",
      "name": "sdasdad",
      "userId": "oetzPCTWihKBgDqdk",
      "playerIds": [
        "43dqNSSs9wWgBEpkf",
        "cGxPc4Rfskr3vYGHm",
        "4Lawd6McmeDK8chaa",
        "3uMZoMiSgn7ANrvLd",
        "FqXwEiGQmsunWWyx3",
        "r2qvzLRwEW5qTSuHm",
        "Cm5neKi3XEpdb3cEF",
        "xRQTh6WLc3RpvbeHQ",
        "o6f8weMiardSknd5x",
        "rdGfYHtp87CG2YWR4",
        "YJnw5TTc6LxH3634h",
        "5rucfgAirfgXhLWac",
        "oQKt3ims4J8YHPGbY",
        "JMPut748RhvkbKHGn",
        "RXjwt93bBKweiuFXm"
      ],
      "history": [
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "score": 32,
          "finalLineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "finalSubs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "autoSubs": []
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "score": 40,
          "finalLineup": null,
          "finalSubs": null,
          "autoSubs": null
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "score": 64,
          "finalLineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "finalSubs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "autoSubs": []
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "o6f8weMiardSknd5x",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "oQKt3ims4J8YHPGbY"
          ],
          "score": 12,
          "finalLineup": [
            "RXjwt93bBKweiuFXm",
            "4Lawd6McmeDK8chaa",
            "5rucfgAirfgXhLWac",
            "JMPut748RhvkbKHGn",
            "3uMZoMiSgn7ANrvLd",
            "43dqNSSs9wWgBEpkf",
            "Cm5neKi3XEpdb3cEF",
            "FqXwEiGQmsunWWyx3",
            "YJnw5TTc6LxH3634h",
            "oQKt3ims4J8YHPGbY",
            "rdGfYHtp87CG2YWR4"
          ],
          "finalSubs": [
            "cGxPc4Rfskr3vYGHm",
            "r2qvzLRwEW5qTSuHm",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x"
          ],
          "autoSubs": [
            {
              "in": "oQKt3ims4J8YHPGbY",
              "out": "o6f8weMiardSknd5x"
            }
          ]
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "5rucfgAirfgXhLWac",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "score": 42,
          "finalLineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "5rucfgAirfgXhLWac",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "finalSubs": [
            "cGxPc4Rfskr3vYGHm",
            "xRQTh6WLc3RpvbeHQ",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "autoSubs": [
            {
              "in": "5rucfgAirfgXhLWac",
              "out": "xRQTh6WLc3RpvbeHQ"
            }
          ]
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "5rucfgAirfgXhLWac",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "score": null,
          "finalLineup": null,
          "finalSubs": null,
          "autoSubs": null
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "5rucfgAirfgXhLWac",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "score": null,
          "finalLineup": null,
          "finalSubs": null,
          "autoSubs": null
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "5rucfgAirfgXhLWac",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "score": null,
          "finalLineup": null,
          "finalSubs": null,
          "autoSubs": null
        },
        {
          "lineup": [
            "RXjwt93bBKweiuFXm",
            "43dqNSSs9wWgBEpkf",
            "r2qvzLRwEW5qTSuHm",
            "FqXwEiGQmsunWWyx3",
            "JMPut748RhvkbKHGn",
            "4Lawd6McmeDK8chaa",
            "oQKt3ims4J8YHPGbY",
            "xRQTh6WLc3RpvbeHQ",
            "o6f8weMiardSknd5x",
            "YJnw5TTc6LxH3634h",
            "rdGfYHtp87CG2YWR4"
          ],
          "subs": [
            "cGxPc4Rfskr3vYGHm",
            "5rucfgAirfgXhLWac",
            "3uMZoMiSgn7ANrvLd",
            "Cm5neKi3XEpdb3cEF"
          ],
          "score": null,
          "finalLineup": null,
          "finalSubs": null,
          "autoSubs": null
        }
      ]
    }
  }
}
```
I even created a `teamHistory(teamId: $teamId)` query just now that all it does is return the history information but again, it only works with graphiql and not apollo client.
I've faced the same problem (in the browser not in RN) with a query resulting in nested arrays. The client get the JSON result back, however the result is empty (as seen from React-apollo). No errors. If I modify the query and remove the nested arrays it is working. And the query with nested arrays is working in GraphiQL.
@helfer this looks like the same bug that I still need to create a test case for :D https://github.com/apollographql/apollo-client/issues/1389
Did you find a work around for it?

If I add an id to the nested query would that help?

On Thu, 6 Apr 2017, 19:17 Andrew E. Rhyne, <notifications@github.com> wrote:

> @helfer <https://github.com/helfer> this looks like the same bug that I
> still need to create a test case for :D #1389
> <https://github.com/apollographql/apollo-client/issues/1389>
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/apollographql/apollo-client/issues/1551#issuecomment-292226356>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AC8oX4u5sRauYZPF3oMYbpPbsRfC2F6dks5rtRAJgaJpZM4M0vwC>
> .
>

In our case, we discovered today that running the graphql HoC twice on a single component with two different queries caused this to happen.
@elie222 definitely try to add an `id` to the nested queries. I intermittently had failed queries (outlined in issue #1518) because the cache couldn't store data without an id. It's error is being swallowed as well, so you're not alerted of the issue.
Well, I think that is different.  If you don't have an ID for a nested type, and you have specified `dataIdFromObject`, it will try to normalized the object under some sort of `undefined` permutation... which means it will probably try to write the different data over and over on the same index.
So adding an `_id` field didn't help at all unfortunately.

I'm dealing with an array of objects btw. These objects shouldn't have ids, but even when I added them, the error remains the same.
I created an error repo for the problem here:
https://github.com/elie222/react-apollo-error-template

If you don't ask for `history` in the query it works fine, but when you do request history, no document is returned to the client.
In my case the problem was related to the server respons not having the exact shape of the query: sometime objects where missing in the answer. However the parsing errors were swallowed. This should have resulted in an error. Instead things where loaded in the store as if everything was working, except I didn't get the data in my React graphql HoC.

BTW: I also tried implementing dataIdFromObject, but it didn't help.
I finally found the source of the error based on your comments @jagare. Note, this is specific to Apollo, all works fine in graphiql and looks like it should work fine. Seems to be a bug with Apollo.

Apollo wasn't happy with me sending `null` in the array.

This works fine:
```
const teamData = {
  _id: 1,
  history: [
    {},
    {lineup: ['a', 'b', 'c']},
    {lineup: ['a', 'b', 'c']},
  ]
}
```

This doesn't work fine:
```
const teamData = {
  _id: 1,
  history: [
    null,
    {lineup: ['a', 'b', 'c']},
    {lineup: ['a', 'b', 'c']},
  ]
}
```

This is the schema we're talking about btw (and in the error repo I posted above):
```
const FixtureHistoryType = new GraphQLObjectType({
  name: 'FixtureHistory',
  fields: {
    lineup: { type: new GraphQLList(GraphQLString) },
  },
});

const TeamType = new GraphQLObjectType({
  name: 'Team',
  fields: {
    _id: { type: GraphQLID },
    history: { type: new GraphQLList(FixtureHistoryType) },
  },
});
```
A different issue I just had with optimistic updates related to arrays of objects again. Again, the silent failure:
https://github.com/apollographql/apollo-client/issues/1566

I figured that one out at least.
Also experiencing a similar problem.  I have multiple id fields which are null.  It looks like apollo is automatically creating a reference hash using the null values (which breaks).
Thanks for the reproduction and detailed error report @elie222. I will look into it tomorrow and will try to fix it asap.
@elie222 I found the bug and fixed it, just have to write a test for it. I'll release it later today :tada:

Patch:
diff --git a/src/data/readFromStore.ts b/src/data/readFromStore.ts
--- a/src/data/readFromStore.ts
+++ b/src/data/readFromStore.ts
@@ -275,7 +275,8 @@ function addPreviousResultToIdValues (value: any, previousResult: any): any {
     // using the private `ID_KEY` property that is added in `resultMapper`.
     if (Array.isArray(previousResult)) {
       previousResult.forEach(item => {
-        if (item[ID_KEY]) {
+        // item can be null
+        if (item && item[ID_KEY]) {
           idToPreviousResult[item[ID_KEY]] = item;
         }
       });


Test patch:
diff --git a/test/QueryManager.ts b/test/QueryManager.ts
--- a/test/QueryManager.ts
+++ b/test/QueryManager.ts
@@ -1201,6 +1201,24 @@ describe('QueryManager', () => {
     });
   });
 
+  it('can handle null values in arrays (#1551)', (done) => {
+    const query = gql`{ list { value } }`;
+    const data = { list: [ null, { value: 1 } ] };
+    const queryManager = mockQueryManager({
+      request: { query },
+      result: { data },
+    });
+    const observable = queryManager.watchQuery({ query });
+
+    observable.subscribe({
+      next: (result) => {
+        assert.deepEqual(result.data, data);
+        assert.deepEqual(observable.currentResult().data, data);
+        done();
+      },
+    });
+  });
+
   it('deepFreezes results in development mode', () => {
     const query = gql`{ stuff }`;
     const data = { stuff: 'wonderful' };
diff --git a/test/roundtrip.ts b/test/roundtrip.ts
--- a/test/roundtrip.ts
+++ b/test/roundtrip.ts
@@ -56,6 +56,21 @@ describe('roundtrip', () => {
     });
   });
 
+   it('array with null values (#1551)', () => {
+    storeRoundtrip(gql`
+      {
+        list {
+          value
+        }
+      }
+    `, {
+      list: [
+        null,
+        { value: 1 },
+      ],
+    });
+  });
+
   it('enum arguments', () => {
     storeRoundtrip(gql`
       {