title: Relay throw error: Cannot read property 'reduce' of undefined
body: <p>I'm trying to create a load more function to my simple application. I fetch data from MySQL using Sequelize and GraphQL. I use relay-starter-kit as the scaffolding for my application.</p>
  
  <p><strong>database.js</strong></p>
  
  <pre><code>import Sequelize from 'sequelize';
  import _ from 'lodash';
  import Faker from 'faker';
  
  const Conn = new Sequelize('relay', 'root', '', {
    host: 'localhost',
    dialect: 'mysql'
  });
  
  const Person = Conn.define('person', {
    firstName: {
      type: Sequelize.STRING,
      allowNull: false
    },
    lastName: {
      type: Sequelize.STRING,
      allowNull: false
    },
    email: {
      type: Sequelize.STRING,
      allowNull: false,
      validate: {
        isEmail: true
      }
    },
    createdAt: {
      type: Sequelize.DATE,
      allowNull: false,
    },
    updatedAt: {
      type: Sequelize.DATE,
      allowNull: false,
    }
  });
  
  const Post = Conn.define('post', {
    title: {
      type: Sequelize.STRING,
      allowNull: false
    },
    content: {
      type: Sequelize.STRING,
      allowNull: false
    }
  });
  
  // Relationships
  Person.hasMany(Post);
  Post.belongsTo(Person);
  
  Conn.sync({ force: true }).then(() =&gt; {
     _.times(10, () =&gt; {
       return Person.create({
         firstName: Faker.name.firstName(),
         lastName: Faker.name.lastName(),
         email: Faker.internet.email(),
         createdAt: Date.now(),
         updatedAt: Date.now()
       }).then(person =&gt; {
         return person.createPost({
           title: `Sample title by ${person.firstName}`,
           content: 'This is a sample article'
         });
       });
     })
   });
  
  // Model types
  class User { }
  
  // Mock data
  var viewer = new User();
  viewer.id = '1';
  
  module.exports = {
    // Export methods that your schema can use to interact with your database
    getUser: (id) =&gt; id === viewer.id ? viewer : null,
    getViewer: () =&gt; viewer,
    Conn
  };
  </code></pre>
  
  <p><strong>schema.js</strong></p>
  
  <pre><code>import {
    GraphQLBoolean,
    GraphQLFloat,
    GraphQLID,
    GraphQLInt,
    GraphQLList,
    GraphQLNonNull,
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLString,
  } from 'graphql';
  
  import {
    connectionArgs,
    connectionDefinitions,
    connectionFromArray,
    connectionFromPromisedArraySlice,
    connectionFromPromisedArray,
    fromGlobalId,
    globalIdField,
    mutationWithClientMutationId,
    nodeDefinitions,
  } from 'graphql-relay';
  
  import {
    // Import methods that your schema can use to interact with your database
    getUser,
    getViewer,
    Conn
  } from './database';
  
  /**
   * We get the node interface and field from the Relay library.
   *
   * The first method defines the way we resolve an ID to its object.
   * The second defines the way we resolve an object to its GraphQL type.
   */
  var {nodeInterface, nodeField} = nodeDefinitions(
    (globalId) =&gt; {
      var {type, id} = fromGlobalId(globalId);
      if (type === 'User') {
        return getUser(id);
      } else {
        return null;
      }
    },
    (obj) =&gt; {
      if (obj instanceof User) {
        return userType;
      } else {
        return null;
      }
    }
  );
  
  /**
   * Define your own types here
   */
  
  const Person = new GraphQLObjectType({
    name: "Person",
    description: "This represents a person",
    fields: () =&gt; {
      return {
        id: {
          type: GraphQLString,
          resolve(person) {
            return person.id
          }
        },
        firstName: {
          type: GraphQLString,
          resolve(person) {
            return person.firstName
          }
        },
        lastName: {
          type: GraphQLString,
          resolve(person) {
            return person.lastName
          }
        },
        email: {
          type: GraphQLString,
          resolve(person) {
            return person.email
          }
        },
        posts: {
          type: new GraphQLList(Post),
          resolve(person) {
            return person.getPosts();
          }
        }
      }
    }
  });
  
  const Post = new GraphQLObjectType({
    name: "Post",
    description: "This is a post",
    fields: () =&gt; {
      return {
        id: {
          type: GraphQLString,
          resolve(person) {
            return person.id;
          }
        },
        title: {
          type: GraphQLString,
          resolve(post) {
            return post.title;
          }
        },
        content: {
          type: GraphQLString,
          resolve(post) {
            return post.content;
          }
        },
        person: {
          type: Person,
          resolve(post) {
            return post.getPerson();
          }
        }
      }
    }
  })
  
  var userType = new GraphQLObjectType({
    name: 'User',
    description: 'A person who uses our app',
    fields: () =&gt; ({
      id: globalIdField('User'),
      people: {
        type: personConnection,
        description: 'A collection of persons',
        args: connectionArgs,
        resolve(_, args, info) {
          console.log("==== INFO ====");
          console.log(info);
          let gas = {};
          gas.first=  args.first;
          gas.after = args.after;
          gas.find = args.find;
          delete args.first;
          delete args.after;
          delete args.find;
          return connectionFromPromisedArray(Conn.models.person.findAll({ where: args }), gas);
        }
      },
    })
  });
  
  var {connectionType: personConnection} =
    connectionDefinitions({ name: 'Person', nodeType: Person });
  
  /**
   * This is the type that will be the root of our query,
   * and the entry point into our schema.
   */
  var queryType = new GraphQLObjectType({
    name: 'Query',
    description: "This is a root query",
    fields: () =&gt; ({
      node: nodeField,
      // Add your own root fields here
      viewer: {
        type: userType,
        resolve: () =&gt; getViewer(),
      }
    }),
  });
  
  /**
   * This is the type that will be the root of our mutations,
   * and the entry point into performing writes in our schema.
   */
  var mutationType = new GraphQLObjectType({
    name: 'Mutation',
    fields: () =&gt; ({
      // Add your own mutations here
    })
  });
  
  /**
   * Finally, we construct our schema (whose starting query type is the query
   * type we defined above) and export it.
   */
  export var Schema = new GraphQLSchema({
    query: queryType,
    types: [queryType, userType, Person, Post]
    // Uncomment the following after adding some mutation fields:
    // mutation: mutationType
  });
  </code></pre>
  
  <p><strong>App.js</strong></p>
  
  <pre><code>import React from 'react';
  import Relay from 'react-relay';
  import AnimateOnChange from 'react-animate-on-change';
  
  class Detail extends React.Component {
    constructor(props) {
      super(props);
      this.state = { person: [] };
    }
    componentWillMount() {
      this.setState({ person: this.props.person });
    }
    render() {
      return (
        &lt;div&gt;
          &lt;h2&gt;Selected User's Detail&lt;/h2&gt;
          &lt;div className="form-group"&gt;
            &lt;label&gt;User ID:&lt;/label&gt;
            &lt;p className="form-control"&gt;
              &lt;AnimateOnChange
                baseClassName="animated"
                animationClassName="fadeIn"
                animate={true}&gt;{this.props.person.id}&lt;/AnimateOnChange&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;div className="form-group"&gt;
            &lt;label&gt;First Name&lt;/label&gt;
            &lt;p className="form-control"&gt;
              &lt;AnimateOnChange
                baseClassName="animated"
                animationClassName="fadeIn"
                animate={true}&gt;{this.props.person.firstName}&lt;/AnimateOnChange&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;div className="form-group"&gt;
            &lt;label&gt;Last Name&lt;/label&gt;
            &lt;p className="form-control"&gt;
              &lt;AnimateOnChange
                baseClassName="animated"
                animationClassName="fadeIn"
                animate={true}&gt;{this.props.person.lastName}&lt;/AnimateOnChange&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;h2&gt;Selected User's Posts&lt;/h2&gt;
          &lt;table className="table table-hovered"&gt;
            &lt;thead&gt;
              &lt;tr&gt;
                &lt;th&gt;No&lt;/th&gt;
                &lt;th&gt;Post ID&lt;/th&gt;
                &lt;th&gt;Title&lt;/th&gt;
                &lt;th&gt;Content&lt;/th&gt;
              &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
              {this.props.person.posts.map((post, key) =&gt;
                &lt;tr key={post.id} className="animated fadeIn"&gt;
                  &lt;td&gt;{key + 1}.&lt;/td&gt;
                  &lt;td&gt;{post.id} {post[key]}&lt;/td&gt;
                  &lt;td&gt;{post.title}&lt;/td&gt;
                  &lt;td&gt;{post.content}&lt;/td&gt;
                &lt;/tr&gt;
              ) }
            &lt;/tbody&gt;
          &lt;/table&gt;
        &lt;/div&gt;
      )
    }
  }
  
  class App extends React.Component {
    constructor(props) {
      super(props);
      this.state = { index: 0 }
    }
    _handleClick(key) {
      if (this.state.index !== key) {
        this.setState({ index: key })
      }
    }
    _loadMore(){
      console.log(this.props.viewer.people);
      this.props.relay.setVariables({
        first: this.props.relay.variables.first,
        after: this.props.viewer.people.pageInfo.endCursor
      });
    }
    render() {
      console.log(this.props.viewer.people);
      return (
        &lt;div className="container"&gt;
          &lt;h2&gt;Users List&lt;/h2&gt;
          &lt;button onClick={this._loadMore.bind(this)}&gt;Load more&lt;/button&gt;
          &lt;ul className="list-group"&gt;
            {this.props.viewer.people.edges.map((p, key) =&gt;
              &lt;li className={key !== this.state.index ? "list-group-item" : "list-group-item active"} onClick={this._handleClick.bind(this, key) } key={p.node.id}&gt;{p.node.firstName} {p.node.lastName} (ID: {p.node.id}) &lt;/li&gt;
            ) }
          &lt;/ul&gt;
          &lt;Detail person={this.props.viewer.people.edges[this.state.index].node}/&gt;
        &lt;/div&gt;
      )
    }
  }
  
  export default Relay.createContainer(App, {
    fragments: {
      viewer: () =&gt; Relay.QL`
        fragment on User {
          people(first: $first, after: $after){
            edges{
              node{
                id,
                firstName,
                lastName,
                posts{
                  id,
                  title,
                  content
                }              
              }
            }
            pageInfo{
              hasNextPage
              hasPreviousPage
              startCursor
              endCursor
            }
          }
        }
      `
    },
    initialVariables: {
      first: 3,
      after: null
    }
  });
  </code></pre>
  
  <p><strong>AppHomeRoute.js</strong></p>
  
  <pre><code>import Relay from 'react-relay';
  
  export default class extends Relay.Route {
    static queries = {
      viewer: (Component) =&gt; Relay.QL`
        query {
          viewer {
            ${Component.getFragment('viewer')}
          }
        }
      `,
    };
    static routeName = 'AppHomeRoute';
  }
  </code></pre>
  
  <p>This application is simple. There is a button that when clicked, will trigger a 'load more' function. You can see the function in App.js. Whenever the function runs, it returns:</p>
  
  <p><code>Cannot read property 'reduce' of undefined</code>.</p>
  
  <p>I've tried to make sure that the query is correct and I found something 'interesting' when I tried to make a query using GraphiQL.</p>
  
  <p>If I use <strong>fragment</strong> (same as the application's way when making request to the server):</p>
  
  <pre><code>query App_ViewerRelayQL($id_0: ID!) {
    node(id: $id_0) {
      id
      ...F0
    }
  }
  
  fragment F0 on User {
    _people35G0DJ: people(after: "YXJyYXljb25uZWN0aW9uOjI=", first: 2) {
      edges {
        node {
          id
          firstName
          lastName
          posts {
            id
            title
            content
          }
        }
        cursor
      }
      pageInfo {
        hasNextPage
        hasPreviousPage
      }
    }
    id
  }
  </code></pre>
  
  <p><strong>Result</strong>:</p>
  
  <pre><code>{
    "errors": [
      {
        "message": "Cannot read property 'reduce' of undefined"
      }
    ]
  }
  </code></pre>
  
  <p>If I <strong>don't use fragment</strong> (raw query):</p>
  
  <pre><code>query {
    viewer {
      id
      people(after:"YXJyYXljb25uZWN0aW9uOjE=",first:2) {
        edges {
          node {
            id
            firstName
            lastName
            posts {
              id
              title
              content
            }
          }
          cursor
        }
        pageInfo {
          hasNextPage
          hasPreviousPage
        }
      }
      id
    }
  }
  </code></pre>
  
  <p><strong>Result</strong>:</p>
  
  <pre><code>{
    "data": {
      "viewer": {
        "id": "VXNlcjox",
        "people": {
          "edges": [
            {
              "node": {
                "id": "3",
                "firstName": "Filomena",
                "lastName": "Ebert",
                "posts": [
                  {
                    "id": "3",
                    "title": "Sample title by Filomena",
                    "content": "This is a sample article"
                  }
                ]
              },
              "cursor": "YXJyYXljb25uZWN0aW9uOjI="
            },
            {
              "node": {
                "id": "4",
                "firstName": "Alessandra",
                "lastName": "Muller",
                "posts": [
                  {
                    "id": "4",
                    "title": "Sample title by Alessandra",
                    "content": "This is a sample article"
                  }
                ]
              },
              "cursor": "YXJyYXljb25uZWN0aW9uOjM="
            }
          ],
          "pageInfo": {
            "hasNextPage": true,
            "hasPreviousPage": false
          }
        }
      }
    }
  }
  </code></pre>
  
  <p>Suppose to be the problem is with the query, but I'm not sure. I'm getting a little bit frustrated right now. Any help would be appreciated.</p>
  
  <p>Thanks.</p>