0

I am having this issue where my resolver will return an error telling me there is null for a non-nullable field, although there clearly is data in my database (as I am looking at it with a sqlite browser). This is because it will return null for the player.id (or the player object completely)

So I am using a model and a schema for graphql and want to return a specific player, which has a flag (active = true). I can return allPlayers just fine and will get all the players. But when filtering like so in my resolver:

async activePlayer(root, args, { models }) {
      return models.Player.findAll({ where: { active: true } });
}

I will receive null data -> thus sending an error, when querying it:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Player.id.",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "activePlayer",
        "id"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field Player.id.",
            "    at completeValue (/usr/src/app/node_modules/graphql/execution/execute.js:560:13)",
            "    at completeValueCatchingError (/usr/src/app/node_modules/graphql/execution/execute.js:495:19)",
            "    at resolveField (/usr/src/app/node_modules/graphql/execution/execute.js:435:10)",
            "    at executeFields (/usr/src/app/node_modules/graphql/execution/execute.js:275:18)",
            "    at collectAndExecuteSubfields (/usr/src/app/node_modules/graphql/execution/execute.js:713:10)",
            "    at completeObjectValue (/usr/src/app/node_modules/graphql/execution/execute.js:703:10)",
            "    at completeValue (/usr/src/app/node_modules/graphql/execution/execute.js:591:12)",
            "    at /usr/src/app/node_modules/graphql/execution/execute.js:492:16",
            "    at async Promise.all (index 0)"
          ]
        }
      }
    }
  ],
  "data": {
    "activePlayer": null
  }
}

Whereas when mapping through the returned promise and console logging it I will get the desired object written to my console:

  async activePlayer(root, args, { models }) {
      models.Player.findAll({ where: { active: true } }).then(player => {
        console.log(player);
      });
    },

Output in console is:

domng-backend | [
domng-backend |   Player {
domng-backend |     dataValues: {
domng-backend |       id: 1,
domng-backend |       name: 'Anna',
domng-backend |       nickname: '',
domng-backend |       active: true,
domng-backend |       createdAt: 2020-02-06T14:16:17.873Z,
domng-backend |       updatedAt: 2020-02-06T14:17:06.684Z,
domng-backend |       gameId: null
domng-backend |     },
domng-backend |     _previousDataValues: {
domng-backend |       id: 1,
domng-backend |       name: 'Anna',
domng-backend |       nickname: '',
domng-backend |       active: true,
domng-backend |       createdAt: 2020-02-06T14:16:17.873Z,
domng-backend |       updatedAt: 2020-02-06T14:17:06.684Z,
domng-backend |       gameId: null
domng-backend |     },
domng-backend |     _changed: {},
domng-backend |     _modelOptions: {
domng-backend |       timestamps: true,
domng-backend |       validate: {},
domng-backend |       freezeTableName: false,
domng-backend |       underscored: false,
domng-backend |       paranoid: false,
domng-backend |       rejectOnEmpty: false,
domng-backend |       whereCollection: [Object],
domng-backend |       schema: null,
domng-backend |       schemaDelimiter: '',
domng-backend |       defaultScope: {},
domng-backend |       scopes: {},
domng-backend |       indexes: [],
domng-backend |       name: [Object],
domng-backend |       omitNull: false,
domng-backend |       sequelize: [Sequelize],
domng-backend |       hooks: {}
domng-backend |     },
domng-backend |     _options: {
domng-backend |       isNewRecord: false,
domng-backend |       _schema: null,
domng-backend |       _schemaDelimiter: '',
domng-backend |       raw: true,
domng-backend |       attributes: [Array]
domng-backend |     },
domng-backend |     isNewRecord: false
domng-backend |   }
domng-backend | ]

So why is that?

Also I have another issue where a reduce function (to calculate sum and avg) will not return the data further below my code. Where sum is just working fine the returned promise will not have a length attribute, thus calculating avg is not possible.

I start to think that my problems are promises and async operations which I do not understand quite right?

Thanks for guidance in any direction at this point.

Best regards and happy coding, Patrick

Patrick Hener
  • 135
  • 5
  • 16
  • Well that looks like this when logging to console, but in my GraphQL Query this is not true. The schema says that the there is an ID. So my understanding is that player.id should be a field to retrieve – Patrick Hener Feb 07 '20 at 11:32
  • @xadm your solution works. It will return an array of players which are active. This will lead to having schema define an array as well. So this might be a solution. Thanks. As I plan on handling just one game for now this is okay, but at frontend (react.js) I'll have to remember that I have to use the first result in the array though. – Patrick Hener Feb 07 '20 at 12:02
  • 1
    https://stackoverflow.com/a/44761334/6124657 – xadm Feb 07 '20 at 12:02
  • @xadm thanks for the link, you are a wizard :thumbsup: PLUS! You also solved my average problem which I was now able to solve this way, too. If there'd be something like reddit gold here I'd give it to you. – Patrick Hener Feb 07 '20 at 12:04

1 Answers1

0

@xadm's comment did the trick. First of all my query will return an array so schema has to be defined to return an array of [Player], plus raw: true will omit all the bogus I don't need (https://stackoverflow.com/a/44761334/6124657).

Thanks again.

Patrick Hener
  • 135
  • 5
  • 16