VikR
VikR

Reputation: 5142

Apollo/GraphQL: Setting Up Resolver for String Fields?

In GraphiQL at http://localhost:8080/graphiql, I'm using this query:

{
  instant_message(fromID: "1"){
    fromID
    toID
    msgText
  }
}

I'm getting this response:

{
  "data": {
    "instant_message": {
      "fromID": null,
      "toID": null,
      "msgText": null
    }
  },
  "errors": [
    {
      "message": "Resolve function for \"instant_message.fromID\" returned undefined",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ]
    },
    {
      "message": "Resolve function for \"instant_message.toID\" returned undefined",
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ]
    },
    {
      "message": "Resolve function for \"instant_message.msgText\" returned undefined",
      "locations": [
        {
          "line": 5,
          "column": 5
        }
      ]
    }
  ]
}

I tried to set up my system according to the examples found here:

https://medium.com/apollo-stack/tutorial-building-a-graphql-server-cddaa023c035#.s7vjgjkb7

Looking at that article, it doesn't seem to be necessary to set up individual resolvers for string fields, but I must be missing something.

What is the correct way to update my resolvers so as to return results from string fields? Example code would be greatly appreciated!

Thanks very much in advance to all for any thoughts or info.

CONNECTORS

import Sequelize from 'sequelize';

//SQL CONNECTORS
const db = new Sequelize(Meteor.settings.postgres.current_dev_system.dbname, Meteor.settings.postgres.current_dev_system.dbuser, Meteor.settings.postgres.current_dev_system.dbpsd, {
  host: 'localhost',
  dialect: 'postgres',

});

db
    .authenticate()
    .then(function(err) {
        console.log('Connection to Sequelize has been established successfully.');
    })
    .catch(function (err) {
        console.log('Unable to connect to the Sequelize database:', err);
    });

const IMModel = db.define('IM', {
    id: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
    fromID: {type: Sequelize.STRING},
    toID: {type: Sequelize.STRING},
    msgText: {type: Sequelize.STRING}
});

IMModel.sync({force: true}).then(function () {
    // Table created
    return IMModel.create({
        fromID: '1',
        toID: '2',
        msgText: 'msg set up via IMModel.create'
    });
});

const IM = db.models.IM;
export {db, IM };

SCHEMA

const typeDefinitions = [`

type instant_message {
  id: Int
  fromID: String
  toID: String
  msgText: String
}
type Query {
  instant_message(fromID: String, toID: String, msgText: String): instant_message
}
type RootMutation {
  createInstant_message(
    fromID: String!
    toID: String!
    msgText: String!
  ): instant_message
}
schema {
  query: Query,
  mutation: RootMutation
}
`];

export default typeDefinitions;

RESOLVERS

import * as connectors from './db-connectors';
import { Kind } from 'graphql/language';
const b = 100;

const resolvers = {
    Query: {
        instant_message(_, args) {
            const a = 100;
            return connectors.IM.find({ where: args });
        }
    },
    RootMutation: {
        createInstant_message: (__, args) => { return connectors.IM.create(args); },
  },

};

export default resolvers;

Upvotes: 0

Views: 1364

Answers (2)

HagaiCo
HagaiCo

Reputation: 706

The issue is that the query does not expect an array, Please fix it: type Query { instant_message(fromID: String, toID: String, msgText: String): [instant_message] }

Then you should make sure the resolver returns Array of objects, if it doesnt work then the resolver is not returning an Array.

Upvotes: 0

Kesem David
Kesem David

Reputation: 2245

When you define your GraphQLObjectTypes you need to provide a resolver for each of their fields.

You defined your instant_message with multiple fields but did not provide resolvers for each of these fields. More over you defined the types of those field with regular typescript fields while you need to define it with GraphQL types (GraphQLInt, GraphQLString, GrapQLFloat etc..)

So defining your type should look something like this:

let instant_message = new GraphQLObjectType({
  id: { 
    type: GraphQLInt,
    resolve: (instantMsg)=> {return instantMsg.id}
  }
  fromID: { 
    type: GraphQLString,
    resolve: (instantMsg)=> {return instantMsg.fromID}
  }
  toID: {
    type: GraphQLString,
    resolve: (instantMsg)=> {return instantMsg.toID}
  }
  msgText: { 
    type: GraphQLString,
    resolve: (instantMsg)=> {return instantMsg.msgText}
  }
})

In addition, you will need to define your Query as follows:

let Query = new GraphQLObjectType({
    name: "query",
    description: "...",

    fields: () => ({
        instant_messages: {
            type: new GraphQLList(instant_message),
            args: {
                id: {type: GraphQLInt}
            },
            resolve: (root, args) => {
                connectors.IM.find({ where: args })
            }
        }
    })
})

Upvotes: 0

Related Questions