为什么Collection.find()在我的Meteor客户端上不起作用?

时间:2018-06-27 18:31:22

标签: javascript mongodb reactjs meteor

我确定正确创建了我的集合,发布了数据,订阅了正确的出版物,并检查了数据是否确实出现在Mongo Shell中。我什至在console.log()中发布了要发布的数据,以确保发布工作正常。但是,以下代码行无法返回任何内容:

const maybeMeet = Meets.find({meetId: maybeId}).fetch();

这可以在下面和链接的仓库中/client/imports/routes/routes.js的第39行中找到。

有一次,我什至尝试创建一个新的Meteor方法'meets.query',该方法将仅发布我需要的所有数据,(不安全地)避免了对发布和订阅的需求(现在已在第59行注释掉了) /client/imports/api/meets.js)。那也没有用。通常,似乎客户端无法从服务器接收任何数据,但是从客户端到服务器的访问似乎可行(我可以将东西插入我的Meets集合中)。

这是问题的根源(routes.js的一部分):

export const routes = (
    <div id='app'>
    <Header />
    <Router history={browserHistory}>
      <Switch>
        <Route exact path="/" render={() => {
          return <Landing />
        }} />
        <Route path="/before" render={() => {
          return <Before />
        }} />
        <Route path="/meet" render={() => {
          Meteor.subscribe('allMeets');

          const maybeId = queryString.parse(location.search).m;

          console.log(typeof maybeId);
          console.log(maybeId);

          const maybeMeet = Meets.find({meetId: maybeId}).fetch(); //***RETURNS NOTHING!***

          return maybeMeet.length ? <Created meet={maybeMeet[0]} /> : <NotFound />;
        }} />
        <Route path="*" render={() => {
          return <NotFound />
        }} />
      </Switch>
    </Router>
  </div>
);

这是我发布数据的地方(“ meets.js”的一部分):

if (Meteor.isServer) {
  Meteor.publish('allMeets', function() {
    return Meets.find();
  });
}

如果需要查看更多代码,请参见完整代码的仓库:https://github.com/kpeluso/meetr

我为混乱的代码致歉-这是一个新项目。

4 个答案:

答案 0 :(得分:1)

这里的问题是订阅操作是异步的,因为它必须从服务器中获取数据。

解决方案是将路由器渲染的组件包装在WithTracker中,以便在数据可用时重新运行,并开始渲染到DOM

有关如何执行此操作的更多信息,请参阅文档: https://guide.meteor.com/react.html#using-withTracker

答案 1 :(得分:1)

WithTracker,检查流星文档https://guide.meteor.com/react.html#using-withTracker

例如,在此代码中,对于APP组件,withTracker可使反应性与订阅保持同步,事物列表将获取集合。

export default withTracker(() => {
  Meteor.subscribe('allThings')
  return {
    things: Things.find({}).fetch()
  }
})(App);

答案 2 :(得分:1)

检查我的流星反应样板。

https://github.com/pkcwong/meteor-react-starter

我使用了软件包meteor/react-meteor-data。 HOF withTracker是正确的解决方案。

答案 3 :(得分:0)

在我的Created组件中,我有一个Tracker.autorun(),里面有一个错误,这导致其他所有崩溃。如上所述,我路由器中对Meteor.subscribe(allMeets);的呼叫也是异步的,因此没有得到处理。

我发现withTracker很麻烦,但从其文档中汲取了很多灵感。结果,我的Created组件中经过编辑的代码现在包含了以下内容:

componentDidMount() {
    this.meetTracker = Tracker.autorun(() => {
      const subHandle = Meteor.subscribe('allMeets');
      const loading = !subHandle.ready();

      const maybeMeet = Meets.find({meetId: this.props.meetId}).fetch();
      if (!maybeMeet.length && loading) {
        this.setState({active: <Loading />});
      } else if (!loading) {
        if (maybeMeet.length) {
          this.setState({active: <During meet={maybeMeet[0]} />});
        } else {
          createHistory().push('/PageNotFound');
          window.location.reload();
        }
      }
    });
  }

...,而我的router中的代码现在包括:

  <Route path="/meet" render={() => {
    const maybeId = queryString.parse(location.search).m;
    return <Created meetId={maybeId} />
  }} />