[SOLVED] useTracker() how to return isLoading the right way?

I have followed the useTracker() methods from the React react-tutorial-master 9: Publications | Meteor React Tutorial

import { Meteor } from 'meteor/meteor';
import React from 'react';
import { useTracker } from 'meteor/react-meteor-data';
import { UnitModelsCollection } from '../../api/unitModels/UnitModelsCollection';

const UnitModelPage = () => {
  const { slug } = useParams();

  const { unitModel, isLoading } = useTracker(() => {
    const noDataAvailable = { unitModel: [] };

    if (!Meteor.user()) {
      return noDataAvailable;
    }

    const unitModelHandler = Meteor.subscribe('unit-model', slug);

    if (!unitModelHandler.ready()) {
      return { ...noDataAvailable, isLoading: true };
    }

    const unitModel = UnitModelsCollection.findOne({ slug: slug });

    return { unitModel };
  }, [slug]);

  if (isLoading) {
    return <p>Loading</p>;
  }

  return (
    <div>
      <div>
        <h1>Model {unitModel.name}</h1>
        <p>Transportpriser</p>
        {unitModel.transportPrices?.map((transport) => (
          <p key={transport.price}>{transport.price}</p>
        ))}
      </div>
    </div>
  );
};

export default UnitModelPage;

My problem is the isLoading value is ‘undefined’ the first 2 times the page is rendered then it is TRUE then back to ‘undefined’.
The result is the page shows without data, switch to loading component and then back to the page now with data.

How to do it the right way?

This may work

const { unitModel, isLoading } = useTracker(() => {
    let unitModel = [];

    if (!Meteor.user()) {
      return { unitModel, isLoading: false };
    }

    const unitModelHandler = Meteor.subscribe('unit-model', slug);
    unitModel = UnitModelsCollection.findOne({ slug: slug });

    return { unitModel, isLoading: !unitModelHandler.ready() };
  }, [slug]);

It’s not working.
isLoading returns: false, false, true, false
But it should return: true, true, true, false

Why do you think it should return true, true, true, false?
your logic has this code

    if (!Meteor.user()) {
      return { unitModel, isLoading: false };
    }

So if user was not logged in, it will never return true.

That was the key, the page is restricted so you are not able to see the page if the user is not login.
I just removed that part and it works as expected.

 const { unitModel, isLoading } = useTracker(() => {
    const noDataAvailable = { unitModel: [] };

    const unitModelHandler = Meteor.subscribe('unit-model', slug);

    if (!unitModelHandler.ready()) {
      return { ...noDataAvailable, isLoading: true };
    }

    const unitModel = UnitModelsCollection.findOne({ slug: slug });

    return { unitModel };
  }, [slug]);

Thanks for your time to help me:)

Sound like you want:

    if (!Meteor.user() && !Meteor.loggingIn()) {
      return { unitModel, isLoading: false };
    }

Because when the page loads it will start logged out, and then attempt a log-in.
So you need to check Meteor.loggingIn() to see if that’s in progress.

This way it’ll prevent the loading: false while a user is still logging in

1 Like