react-packages icon indicating copy to clipboard operation
react-packages copied to clipboard

react-meteor-data :: Chaining dependent information - best practice?

Open ensemblebd opened this issue 3 years ago • 0 comments

Let's say you have a Company object, and associated Persons bound by a lookup field. And say you want to output the combined information.

Is this really the best pattern?

const ID = 1234; // params.id from react-router for example.

const {loadingCompany, company} = useTracker(() => {
	const handles = [
		Meteor.subscribe("aCompany", ID),
	];
	const company = 	ACompany.findOne();

	return {
		loadingCompany: !handles.every(h=>h.ready()),
		company
	};
}, []);

console.log(company);
// >    { _id: 0, name: "abc", OwnerID: 321 }

// now we access OwnerID within the resultant, and subscribe to that person: 
const {loadingOwner, owner} = useTracker(() => {
	if (loadingCompany || !company) return {loadingCompany: true, company: {}}; // such that usages in react render don't crash.
	
	const handles = [
		Meteor.subscribe("People", company.OwnerID),
	];
	const owner = 	People.findOne();

	return {
		loadingOwner: !handles.every(h=>h.ready()),
		owner
	};
}, [loadingCompany, company]);


// logic to check the above before attempting to use it..
const [fullyLoaded, setFullyLoaded ] = React.useState(false);

React.useEffect(() => {
	if (![company,owner].every(x=> (x && x._id) )) return ; // null check while subscription is loaded, but materialization has yet to complete into the actual data object..

	// trigger render cycle now that we actually have data available.
	setFullyLoaded(true);
}, [company,owner]);

return (<div>
	{ !fullyLoaded? 
		<span>Loading..</span>
	: 
		<span> {company.name} is owned by:  ${owner.name} </span>
	}
</div>);

I'm just trying to figure out a cleaner way I guess. If you utilize React-Router, you won't have the target ID until the user hits the browser url target. So you can't pre-subscribe, without loading ALL data into mini-mongo on the client. And if you are to subscribe and query mini mongo at time of page load and render, you have to wait for all the data to be available.

After reading this: https://blog.meteor.com/introducing-usetracker-react-hooks-for-meteor-cb00c16d6222 I am thus aware that HOC, context, and hooks can be used to split out Subs from data query loads. But the above example keeps the concept simple, since doing any of that is precisely the same, just looks like less code. React Context's perhaps I could see the value there i suppose.. by wrapping HOC providers. Is that how you do it?

It's just the business logic of that that feels so extremely dirty. Sub one, load one. Wait. Sub 2nd, load 2nd. Wait. Check if non-null.. Render Cycle. Technically that's 5 or 6 render cycles.

Surely there is a better way?

ensemblebd avatar Aug 19 '22 08:08 ensemblebd