Subscriptions ready fires before Data has arrived (React)
See original GitHub issueSo i am having an issue with a subscription being ready before the data has fully been served to the client. I am using ReactJS as a templating engine and I am passing the a user
property to child templates. When i come to a setting page I need to subscribe to a specific piece of the users account and display that information in input fields to be edited.
However,
if the data has not quite hit the client the subscription is being set to ready before the template has the data to render. I’m not sure if its react slowing things down or what but here are a few example snippets that have been striped down.
LayoutTemplate
PortalLayout = React.createClass({
mixins : [ReactMeteorData],
getMeteorData () {
return {
user : Meteor.user()
}
},
componentDidMount() {
let instance = this;
instance.tracker = Tracker.autorun(function () {
FlowRouter.watchPathChange();
if (instance.isMounted()) {
let holder = instance.state;
holder.current = FlowRouter.current();
instance.setState(holder);
}
});
},
componentWillUnmount () {
this.tracker.stop()
},
render() {
if(!this.data.user) {
return <div></div>
}
return (
<div className="main-container">
{ React.cloneElement(this.props.content, { user: this.data.user }) }
</div>
)
}
Child Template
InsuranceSettings = React.createClass({
componentDidMount () {
let instance = this;
instance._tracker = Tracker.autorun(function () {
let user = Meteor.user();
let holder = instance.state;
if(user && user.documents) {
holder.exempt = user.documents.exempt;
}
holder.ready = FlowRouter.subsReady();
instance.setState(holder);
});
},
componentWillUnmount() {
this._tracker.stop();
},
getInitialState () {
return {
exempt : 'no',
ready : FlowRouter.subsReady()
}
},
setExempt (event) {
let holder = this.state;
holder.exempt = $(event.target).val();
this.setState(holder);
},
render () {
let instance = this;
if(!instance.state.ready || (instance.props.user && instance.props.user.documents && !instance.props.user.documents.glExp ))
return (<div></div>);
return (
<div className="settings page block" id="account-settings">
<form className="centered" ref="form">
<h2>Insurance</h2>
<label>General Liability</label>
< FileUpload uploader="documents" name="gl" file={instance.props.user.documents && instance.props.user.documents.gl || null } />
<label>General Liability Expiration</label>
<input type="text" name="glExp" data-date defaultValue={instance.props.user.documents && instance.props.user.documents.glExp && instance.props.user.glExpDate() || '' } />
<button type="button" className="pull-right" >Update Account</button>
</form>
</div>
)
}
});
Since React’s defaultValue
only sets the value on load i have to check if the values exist and if they don’t if(!instance.state.ready || (instance.props.user && instance.props.user.documents && !instance.props.user.documents.glExp ))
then I have to render nothing until they do. But this doesnt always work because if glExp
is sent before gl
then glExp
will have a value but gl
won’t.
If anyone has any ideas solutions or if this is the wrong place to ask this please let me know.
Thank you.
Issue Analytics
- State:
- Created 8 years ago
- Comments:9 (5 by maintainers)
Top GitHub Comments
Okay. Here’s the issue. getMeteorData() does more stuff and when manually setting state. There could be some conflict. So, I advice you to put flow router code on the
getMeteorData
itself. Then it’ll work without any issues.I’m now using react-router plus react-meteor-data instead of flow-router - works perfectly.