Search code examples
reactjsmeteormongodb-querymeteor-react

createContainer() Cannot retrieve object by ID


I am currently building a noughts and crosses game with Meteor and React. When I first start the app, I create a new item in the 'Games' collection and send the id of this object to the App as a prop:

Meteor.startup(() => {
    Meteor.call('games.create', function(error, result) {
        var id = result;
        render(<App gameId={id} />, document.getElementById('render-target'));
    });
});

I then use createContainer on the App component to retrieve the Game on the Database, so I can manipulate it within the App:

export default createContainer(({gameId}) => {
  Meteor.subscribe('games');
  console.log(gameId);
  return {
    gameState: Games.find(ObjectId(gameId)).fetch(),
  };
}, App);

After I added this createContainer code, the app stopped rendering. In the console, I get a very long error message, copied below. Thanks in advance!

Exception in delivering result of invoking 'games.create': require<.imports.ui["App.jsx"]</exports.default<@http://localhost:3000/app/app.js?hash=d138fc2a4d2ee444a0b4b78d568bc9e3acf71f7c:758:5
getMeteorData@http://localhost:3000/packages/react-meteor-data.js?hash=913595fb1851d69206a4cd0ce5bfbacdc56a8830:282:16
calculateData/this.computation</<@http://localhost:3000/packages/react-meteor-data.js?hash=913595fb1851d69206a4cd0ce5bfbacdc56a8830:164:22
Tracker.Computation.prototype._compute@http://localhost:3000/packages/tracker.js?hash=9f8a0cec09c662aad5a5e224447b2d4e88d011ef:339:5
Tracker.Computation@http://localhost:3000/packages/tracker.js?hash=9f8a0cec09c662aad5a5e224447b2d4e88d011ef:229:5
Tracker.autorun@http://localhost:3000/packages/tracker.js?hash=9f8a0cec09c662aad5a5e224447b2d4e88d011ef:604:11
calculateData/this.computation<@http://localhost:3000/packages/react-meteor-data.js?hash=913595fb1851d69206a4cd0ce5bfbacdc56a8830:156:16
Tracker.nonreactive@http://localhost:3000/packages/tracker.js?hash=9f8a0cec09c662aad5a5e224447b2d4e88d011ef:631:12
calculateData@http://localhost:3000/packages/react-meteor-data.js?hash=913595fb1851d69206a4cd0ce5bfbacdc56a8830:155:26
componentWillMount@http://localhost:3000/packages/react-meteor-data.js?hash=913595fb1851d69206a4cd0ce5bfbacdc56a8830:66:21
require<.node_modules["react-dom"].lib["ReactCompositeComponent.js"]</ReactCompositeComponent.performInitialMount/<@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18931:18
measureLifeCyclePerf@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18658:12
require<.node_modules["react-dom"].lib["ReactCompositeComponent.js"]</ReactCompositeComponent.performInitialMount@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18930:9
require<.node_modules["react-dom"].lib["ReactCompositeComponent.js"]</ReactCompositeComponent.mountComponent@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18841:16
require<.node_modules["react-dom"].lib["ReactReconciler.js"]</ReactReconciler.mountComponent@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:11766:18
require<.node_modules["react-dom"].lib["ReactCompositeComponent.js"]</ReactCompositeComponent.performInitialMount@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18954:18
require<.node_modules["react-dom"].lib["ReactCompositeComponent.js"]</ReactCompositeComponent.mountComponent@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:18841:16
require<.node_modules["react-dom"].lib["ReactReconciler.js"]</ReactReconciler.mountComponent@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:11766:18
mountComponentIntoNode@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:23920:16
require<.node_modules["react-dom"].lib["Transaction.js"]</TransactionImpl.perform@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:12730:13
batchedMountComponentIntoNode@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:23942:3
require<.node_modules["react-dom"].lib["Transaction.js"]</TransactionImpl.perform@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:12730:13
require<.node_modules["react-dom"].lib["ReactDefaultBatchingStrategy.js"]</ReactDefaultBatchingStrategy.batchedUpdates@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:21609:14
batchedUpdates@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:11398:10
require<.node_modules["react-dom"].lib["ReactMount.js"]</ReactMount._renderNewRootComponent@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:24136:5
require<.node_modules["react-dom"].lib["ReactMount.js"]</ReactMount._renderSubtreeIntoContainer@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:24217:21
require<.node_modules["react-dom"].lib["ReactMount.js"]</ReactMount.render@http://localhost:3000/packages/modules.js?hash=b2852da4b705e3b46ab5b20c9b94e15e453af050:24238:12
require<.client["main.js"]</</<@http://localhost:3000/app/app.js?hash=d138fc2a4d2ee444a0b4b78d568bc9e3acf71f7c:395:3
Meteor.bindEnvironment/<@http://localhost:3000/packages/meteor.js?hash=e3f53db3be730057fed1a5f709ecd5fc7cae1229:1105:17
._maybeInvokeCallback@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3557:7
.receiveResult@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3577:5
._livedata_result@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:4742:7
Connection/onMessage@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:3385:7
._launchConnection/self.socket.onmessage/<@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2736:11
_.forEach@http://localhost:3000/packages/underscore.js?hash=cde485f60699ff9aced3305f70189e39c665183c:149:7
._launchConnection/self.socket.onmessage@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:2735:9
REventTarget.prototype.dispatchEvent@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:175:9
SockJS.prototype._dispatchMessage@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1160:5
SockJS.prototype._didMessage@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1218:13
SockJS.websocket/that.ws.onmessage@http://localhost:3000/packages/ddp-client.js?hash=bc32a166cd269e06a394f9418e0024d805bab379:1365:9

Solution

  • Your problem is the ObjectId() meteor doesn't know how to handle it. do the following:

    export default createContainer(({gameId}) => {
    Meteor.subscribe('games');
      console.log(gameId);
      return {
        gameState: Games.find(new Meteor.Collection.ObjectID(gameId)).fetch(),
      };
    }, App);
    

    Ideally you need to use the Subscription as a handler:

    export default createContainer(({ gameId }) => {
    const gamesHandle    = Meteor.subscribe('games');
    const isLoadingGames = !gamesHandle.ready()
    const gamesState     = Games.find({ _id: gameId }).fetch() // <-- make sure 'Games' is imported or avilable globally
    return {
      gamesState,
      isLoadingGames
    };
    }, App);
    

    Then you can access this.props.isLoadingGames in your <App /> component and use it to display a loading :) e.x this.props.isLoadingGames ? 'Loading...' : 'Finished...'