Search code examples
meteormeteor-reactmeteor-tracker

Why findOne() doesn't work in withTracker() section but it does work in render() method?


Meteor and React. I am trying to subscribe two collections of mongo, and use a particular document to pass it to a component. If I try to get the document in the whitTracker () section it seems that it will search for it before synchronizing the document and returns indefinitely. But, if I do it in the render section, after making sure that isLoading is false, then it works. Where is the right place to find data from collections to which I subscribed?

This (making query in withTracker section) doesn't work: laLoca and laLoca1 will be undefined.

    render() {
        if (this.props.isLoading) {
          return <LoaderExampleText />;
        }        

        return (<MyMap laLoca={this.props.laLoca} />);
      }
    }

    export default withTracker(() => {
      const handles = [
        Meteor.subscribe("wells"),
        Meteor.subscribe("locaciones"),
        Meteor.subscribe("Drylocationlast")
      ];
      const isLoading = handles.some(handle => !handle.ready());
      const laLoca1 = Drylocationlast.findOne({ codigo: "dl" });
      const laLoca = Locaciones.findOne(laLoca1.dryLocationId);

      return {
        laLoca:laLoca,
        wells: Wells.find().fetch(),
        isLoading: isLoading
      };
    })(WellHome);

But this ( make the query in render method), does work:

    render() {
        if (this.props.isLoading) {
          return <LoaderExampleText />;
        }
        const laLoca1 = Drylocationlast.findOne({ codigo: "dl" });
        const laLoca = Locaciones.findOne(laLoca1.dryLocationId);

        return (<MyMap laLoca={laLoca} />);
      }
    }

    export default withTracker(() => {
      const handles = [
        Meteor.subscribe("wells"),
        Meteor.subscribe("locaciones"),
        Meteor.subscribe("Drylocationlast")
      ];
      const isLoading = handles.some(handle => !handle.ready());

      return {
        wells: Wells.find().fetch(),
        isLoading: isLoading
      };
    })(WellHome);

Solution

  • If laLoca1 is undefined, laLoca1.dryLocationId will crash (you see an error in the console, right?), and I imagine the tracking will not be setup correctly.

    When you put:

    const laLoca1 = Drylocationlast.findOne({ codigo: "dl" });
    const laLoca = Locaciones.findOne(laLoca1.dryLocationId);
    

    in render() after you have verified that the subscriptions are ready, they will never be undefined, and it will work.

    I think optimally, render() should not be responsible for fetching data, only to visualize it. In withTracker() you can do something like this:

    const isLoading = handles.some(handle => !handle.ready());
    
    if(isLoading){
      return {
        laLoca: null,
        wells: null,
        isLoading: true
      };
    }else{
      const laLoca1 = Drylocationlast.findOne({ codigo: "dl" });
      const laLoca = Locaciones.findOne(laLoca1.dryLocationId);
      return {
        laLoca: laLoca,
        wells: Wells.find().fetch(),
        isLoading: false
      };
    }