Skip to content

Instantly share code, notes, and snippets.

@duwerq
Last active March 12, 2020 00:20
Show Gist options
  • Save duwerq/b16d8c8739f95ca52509f7a471b4d1d4 to your computer and use it in GitHub Desktop.
Save duwerq/b16d8c8739f95ca52509f7a471b4d1d4 to your computer and use it in GitHub Desktop.
const dashboardQueries = [
{
queryEnhancer: {
query: gql(queries.getUser),
fetchPolicy: 'cache-first',
dataKey: 'user',
queryKey: 'getUser'
}
},
]
const DashboardComponent = WrappedComponent(Dashboard, dashboardQueries);
import React, { Component } from 'react';
import { withApollo } from 'react-apollo';
export default options => (WrappedComponent) => {
class QueryEnhancer extends Component {
constructor(props) {
super(props);
this.state = {
[`${this.props.options.dataKey}`]: {},
[`${this.props.options.dataKey}Loading`]: false,
[`${this.props.options.dataKey}Error`]: null,
[`${this.props.options.dataKey}NetworkStatus`]: 7
};
}
componentDidMount() {
// If you're using React-Native, make sure to change this.props.location.state to this.props.navigation.state
const {
params,
} = this.props.location.state || {};
if (this.props.options && this.props.options.fetchPolicy === 'cache-and-network') {
this.watchQuery(params || {});
}
this._query(params || {});
}
componentWillUnmount() {
if (Object.keys(this.observable).length > 0) this.observable.unsubscribe();
}
watchQuery = async (m) => {
const { options, client } = this.props;
const watchedQuery = client.watchQuery({
query: options.query, variables: m
});
this.observable = watchedQuery.subscribe({
next: async ({ data }) => {
let freshData = data;
if (typeof options.resolver === 'function') {
freshData = await options.resolver(data[options.queryKey], client);
}
this.setState({
[`${options.dataKey}`]: freshData[options.queryKey],
});
}
});
}
observable = {}
_query = async (m, watchQuery) => {
const { options, client } = this.props;
if (this.state[`${options.dataKey}Loading`] === false) {
if (options.fetchPolicy === 'cache-only') {
const { data: cacheData } = await client.query({
query: options.query,
variables: m,
fetchPolicy: 'cache-only'
});
this.setState({ [`${this.props.options.dataKey}`]: cacheData[options.queryKey], [`${this.props.options.dataKey}Loading`]: false });
} else if (typeof options.resolver === 'function') {
this.setState({ [`${options.dataKey}Loading`]: true });
try {
const newQuery = await client.query({
query: options.query,
variables: m,
fetchPolicy: 'no-cache'
});
if (newQuery && newQuery.data[options.queryKey]) {
const resolvedData = await options.resolver(newQuery.data[options.queryKey], client);
if (resolvedData) {
client.writeQuery({
query: options.query,
data: resolvedData
});
}
this.setState({
[`${options.dataKey}Loading`]: false,
[`${options.dataKey}`]: resolvedData[options.queryKey],
[`${options.dataKey}NetworkStatus`]: newQuery.networkStatus
});
}
} catch (error) {
this.setState({
[`${options.dataKey}Loading`]: false,
[`${options.dataKey}Error`]: error,
// [`${options.dataKey}NetworkStatus`]: newQuery.networkStatus
});
}
} else {
this.setState({ [`${options.dataKey}Loading`]: true });
try {
const newQuery = await client.query({
query: options.query,
variables: m,
fetchPolicy: options.fetchPolicy === 'cache-and-network' ? 'network-only' : options.fetchPolicy
});
if (newQuery) {
this.setState({
[`${options.dataKey}Loading`]: false,
[`${options.dataKey}`]: newQuery.data[options.queryKey],
[`${options.dataKey}NetworkStatus`]: newQuery.networkStatus
});
}
} catch (error) {
this.setState({
[`${options.dataKey}Loading`]: false,
[`${options.dataKey}Error`]: error,
// [`${options.dataKey}NetworkStatus`]: newQuery.networkStatus
});
}
}
} return null;
}
render() {
return (<WrappedComponent
{...{
...this.props,
...this.state,
options: {},
[`${this.props.options.dataKey}Refetch`]: m => this._query(m)
// [`${this.props.options.dataKey}`]: m => this._query(m)
}}
/>);
}
}
QueryEnhancer.displayName = `QueryEnhancer(${options.dataKey})`;
return withApollo(props => <QueryEnhancer {...{ ...props, options }} />);
};
import flow from 'lodash/flow';
// import MutationEnhancer from './MutationEnhancer';
import QueryEnhancer from './QueryEnhancer';
// const mutationParams = ({
// fetchPolicy,
// mutationKey,
// mutation,
// mutationUpdate
// }) => MutationEnhancer({
// mutation, mutationUpdate, mutationKey, fetchPolicy
// });
const queryEnhancerParams = ({
fetchPolicy,
queryKey,
query,
returnFn,
dataKey,
subscribe,
updateQuery,
resolver,
}) => QueryEnhancer({
fetchPolicy,
queryKey,
query,
returnFn,
dataKey,
subscribe,
updateQuery,
resolver
});
const createQuery = ({
queryEnhancer: query => queryEnhancerParams(query)
});
const graphqlQueries = queries => queries.map((fn) => {
const queryType = Object.keys(fn)[0];
const params = fn[`${queryType}`];
const composeQuery = createQuery[`${queryType}`];
const composedQuery = composeQuery(params);
return composedQuery;
});
const wrappedComponent = (component, fnQueries) => (fnQueries ?
flow(...graphqlQueries(fnQueries))(component) :
component
);
// class WrappedComponet extends React.Component {
// queryChildren
// }
export default wrappedComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment