中继/ Mongodb错误 - 无法读取未定义

时间:2017-01-17 11:36:16

标签: mongodb graphql relayjs objectid react-starter-kit

我有一个测试relay-starter-kit项目,其中包含一个自动填充搜索表单,可以向浏览器显示引号。当我使用搜索表单时,我在浏览器中收到错误" app.js:8284 Uncaught TypeError:无法读取属性' edge'未定义"。我无法理解为什么它第一次填充搜索字段而不是在搜索表单中输入。值得注意的是,如果您对searchTerm变量进行硬编码,它将呈现搜索结果。换句话说,它可以在硬编码时读取边缘。对此的任何指导都会很棒。感谢。

架构为here 这是搜索词的有效graphql查询不会呈现的组件。

    import React from 'react';
    import Relay from 'react-relay';
    import { debounce } from 'lodash';
    import SearchForm from '../search-form';
    import Quote from '../quote';

    class App extends React.Component {
        constructor(props) {
        super(props)
        this.search = debounce(this.search.bind(this), 300)
      }
      search(searchTerm) {
        this.props.relay.setVariables({ searchTerm });
      }

      render() {
        return (
          <div className="quotes-library">
            <SearchForm searchAction={this.search} />
            <div className="quotes-list">
              {this.props.viewer.quotes.edges.map(edge =>
                <Quote key={edge.node.id} quote={edge.node} />
              )}
            </div>
          </div>
        )
      }
    }

    export default Relay.createContainer(App, {
      initialVariables: {
        searchTerm: '',
      },
      fragments: {
        viewer: () => Relay.QL`
          fragment on User {
                quotes(first:100, searchTerm: $searchTerm) {
                    edges {
                        node {
                            id
                            ${Quote.getFragment('quote')}
                        }
                    }
                }
            }
        `,
      },
    });

更新:这是Chrome DevTools网络标签中显示的查询。请注意&#39; p&#39;正在查询对搜索表单的输入。

    query App_ViewerRelayQL($id_0:ID!) {
  node(id:$id_0) {
    ...F2
  }
}
fragment F0 on Quote {
  id,
  likesCount
}
fragment F1 on Quote {
  text,
  author,
  id,
  ...F0
}
fragment F2 on User {
  _quotes3UfnML:quotes(first:100,searchTerm:"pri") {
    edges {
      node {
        id,
        ...F1
      },
      cursor
    },
    pageInfo {
      hasNextPage,
      hasPreviousPage
    }
  },
  id
}

将console.log添加到render()会显示searchTerm输入:

 app.js:17
   {
    "viewer": {
        "__dataID__": "VXNlcjox",
        "__status__": 4
    },
    "relay": {
        "pendingVariables": null,
        "route": {
            "name": "AppHomeRoute",
            "params": {},
            "queries": {}
        },
        "variables": {
            "searchTerm": "pri"
        }
    }
}

app.js第24行发生以下错误,即{this.props.library.quotes.edges.map(edge => <Quote key={edge.node.id} quote={edge.node} /> )}

app.js:8285 Uncaught TypeError: Cannot read property 'edges' of undefined
    at App.render (app.js:8285)
    at app.js:43197
    at measureLifeCyclePerf (app.js:42476)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (app.js:43196)
    at ReactCompositeComponentWrapper._renderValidatedComponent (app.js:43223)
    at ReactCompositeComponentWrapper._updateRenderedComponent (app.js:43147)
    at ReactCompositeComponentWrapper._performComponentUpdate (app.js:43125)
    at ReactCompositeComponentWrapper.updateComponent (app.js:43046)
    at ReactCompositeComponentWrapper.receiveComponent (app.js:42948)
    at Object.receiveComponent (app.js:35341)

更新2:

所以检查一下。我的{ObjectID}做错了。我拉了一个用户并从数据库中引用了一个&#39; _id&#39;但没有&#39; id&#39;对象上的属性。这是输出:

 > db.users.find({})
{ "_id" : ObjectId("586253169465191cb812066c"), "name" : "me", "id" : ObjectId("586253169465191cb812066c"), "errors" : [ ] }
> db.quotes.find({})
{ "_id" : ObjectId("586693333ff93f3581c0ca05"), "text" : "Hi Prisc", "author" : "H. Jackson Brown", "likesCount" : 24 }
{ "_id" : ObjectId("586693333ff93f3581c0ca06"), "text" : "If opportunity doesn't knock, build a door", "author" : "Milton Berle", "likesCount" : 2 }
{ "_id" : ObjectId("586693333ff93f3581c0ca07"), "text" : "Try to be a rainbow in...", "author" : "Maya Angelou" }

如果我从globalIdFetcher()中记录id,那么Jackson Brown Quote对象的记录ID会按预期显示两个id,但它们都与db中的id相同且不同。控制台中的输出是:

{
    "viewer": {
        "__dataID__": "VXNlcjo=",
        "quotes": {
            "__dataID__": "client:6068631311_first(100),searchTerm()",
            "edges": [
                {
                    "__dataID__": "client:client:6068631311:UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
                    "node": {
                        "__dataID__": "UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
                        "id": "UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
                        "__fragments__": {
                            "1::client": [
                                {
                                    "showLikes": false
                                }
                            ]
                        }
                    }
                },

有关修复此语法的任何想法吗?

2 个答案:

答案 0 :(得分:0)

使用所提供的信息解决问题非常困难。当您请求指导时,这是我的建议:)

  

我无法理解为什么它第一次填充搜索字段而不是在搜索表单中输入。

因为Relay获取searchTerm的初始值的结果,在您的情况下这是一个空字符串。您必须在服务器端处理此情况(通过检查输入searchTerm)和客户端(例如,通过检查searchTerm的当前值是否为空)。

当您输入搜索表单时,系统不会调用search(),也不会更新searchTerm。检查SearchForm组件。

  

当我使用搜索表单时,我在浏览器中收到错误“app.js:8284 Uncaught TypeError:无法读取未定义的属性'edge'。

开始调试服务器端为quotes GraphQL对象类型下的viewer字段返回的内容。模式中db.collection('quotes').find(findParams).toArray()的输出是什么?另外,在console.log(JSON.stringify(this.props, null, 4))类的render()函数中添加App。检查你看到了什么。您还可以在Chrome DevTools网络选项卡上检查HTTP请求和响应。按graphql过滤。

答案 1 :(得分:0)

解决方案是将Quote类型从nodeInterface中取出,这样只通过nodeInterface运行顶级对象,让relay从GraphQLID或fromGlobalId生成objectId的id,如各个itemType中所定义。