Closed SachaG closed 7 years ago
As myself and @SachaG had discussed on Slack, the other option might be to setup an Apollo subscription that notifies if the logged-in user changes. Obviously this involves adding hooks into all the server-side log in/out functions.
If Meteor.user()
is already being updated by Meteor pubsub, you could use that instead of currentUser
query?
If you keep the query, using an apollo sub seems more efficient than the refetch autorun, but either would work.
Either way, can deal with not rendering on user doc changes with shouldComponentUpdate
? Not familiar with loading
, but could make an loadingInitialData
flips-one-way var out of it. Starting:
loading = true
loadingInitialData = true
and on every change:
if (!loading)
loadingInitialData = false
OK, so here's what I get using Meteor.user()
(let's call it "Strategy A"). It's not ideal in the sense that it's still relying on DDP, but it seems to work.
In this example, let's say I want my global app container to wait for both the current user and a list of categories
(loaded via Apollo) to load before loading the rest of my app:
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import { composeWithTracker } from 'react-komposer';
// first HoC that gets user loaded via DDP
const currentUserComposer = (props, onData) => {
onData(null, {currentUser: Meteor.user()});
}
// second HoC that gets Apollo data
const AppContainer = props => {
return <Telescope.components.App
ready={!props.data.loading} // from Apollo
categories={props.data.categories} // from Apollo
currentUser={props.currentUser} // from currentUserComposer
{...props} // pass on other props (router, etc.)
/>;
};
const AppContainerWithData = graphql(gql`
query getAppData {
categories {
_id
name
}
}
`)(AppContainer);
module.exports = composeWithTracker(currentUserComposer)(AppContainerWithData);
Looks good. And then in Telescope.components.App
, you could do
render() {
const userDataIsLoading = Meteor.userId() && !props.currentUser
if (!props.ready || userDataIsLoading) {
return <Loading />
}
...
}
Or make a loading
prop inside currentUserComposer
that took into account both props.ready
and userDataIsLoading
I think the generally recommended strategy is to call resetStore()
when the user changes, is that right @helfer?
Where would you call it from? Autorun block with Meteor.user()
inside it? Also, where is resetStore
documented? Would it reset the entire store or is it ok to just rerun one specific query?
It re-runs all queries. I guess in an autorun block makes sense?
http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.resetStore (not really documented per-se ;) )
What if you only wanted to rerun one specific query?
I guess you could just call refetch
on it?
@tmeasday yep, that's all correct! I just fixed resetStore
, so it should actually work now 🙂
Thanks @helfer, client.resetStore()
works well! We use it with login/logout hooks of std:accounts-ui
🚀
Closing as it's now documented and working well 👌
@SachaG are you using meteor on the client for accounts, or are you doing a all graphql implementation similar to meteor-apollo-accounts?
We're using Meteor for the accounts with DDP, but yeah ideally we would have a graphql implementation…
I currently have a
currentUser
query in my global app container that loads the current user, and I'm handling user accounts through the accounts-ui package.The problem is that the Apollo query doesn't know it needs to re-run when the Meteor user's logged in/logged out state changes.
So the flow looks something like this:
currentUser
which returns nothing because no user is logged in.currentUser
to get the current user profile.As you can see things break down at step 3. What's the best way of telling the query to rerun? One solution would be calling
refetch()
in an autorun block containingMeteor.user()
?Another issue related to the way I've currently set things up is that refetching the
currentUser
query would force my entire app to reload:Is there a way to rerun the query without setting
loading
tofalse
? Or a better pattern for setting up your app container?