Last active
January 8, 2022 23:14
-
-
Save copleykj/19886511fc10fac3c990061c8f8bbf23 to your computer and use it in GitHub Desktop.
Grapher Hooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect, useRef } from 'react'; | |
import { useTracker } from 'meteor/react-meteor-data'; | |
import { Grapher } from 'meteor/cultofcoders:grapher'; | |
import { Meteor } from 'meteor/meteor'; | |
interface QueryInfo<T> { | |
loading: boolean | |
ready: boolean | |
data: T[] | |
error: Meteor.Error | null | |
} | |
interface QueryParams<T> { | |
query: Grapher.Query<T> | |
params?: any | |
} | |
const withReactiveQuery = function <T>({ query, params = {} }: QueryParams<T>): QueryInfo<T> { | |
const [subscriptionError, setSubscriptionError] = useState<Meteor.Error | null>(null); | |
const [isLoading, setIsLoading] = useState<boolean>(true); | |
const [isReady, setIsReady] = useState<boolean>(false); | |
const subscriptionHandle = useRef<Meteor.SubscriptionHandle | undefined>(undefined); | |
const queryRef = useRef<Grapher.Query<T> | undefined>(undefined); | |
const depends = Object.values(params); | |
const queryInfo: QueryInfo<T> = useTracker(() => { | |
let data: QueryInfo<T>['data'] = []; | |
useEffect(() => { | |
queryRef.current = query.clone(params); | |
console.log('using effect'); | |
setSubscriptionError(null); | |
setIsLoading(true); | |
setIsReady(false); | |
subscriptionHandle.current = queryRef.current?.subscribe({ | |
onStop (err) { | |
if (typeof err !== 'undefined') { | |
console.log('subscriptiong stopped'); | |
setSubscriptionError(err); | |
} | |
setIsLoading(false); | |
}, | |
onReady () { | |
setSubscriptionError(null); | |
setIsLoading(false); | |
setIsReady(true); | |
}, | |
}); | |
return () => { subscriptionHandle?.current?.stop(); }; | |
}, depends); | |
if (typeof queryRef.current !== 'undefined' && isReady) { | |
data = queryRef.current.fetch(); | |
} | |
return { | |
loading: isLoading, | |
ready: isReady, | |
data, | |
error: subscriptionError, | |
}; | |
}); | |
return queryInfo; | |
}; | |
export default withReactiveQuery; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect, useMemo } from 'react'; | |
import { Grapher } from 'meteor/cultofcoders:grapher'; | |
import { Meteor } from 'meteor/meteor'; | |
interface QueryInfo<T> { | |
loading: boolean | |
refetch: () => void | |
data: T[] | |
count: number | undefined | |
error: Meteor.Error | null | |
} | |
interface FetchConfig { | |
loadOnRefetch?: boolean | |
fetchTotal?: boolean | |
} | |
interface QueryParams<T> { | |
query: Grapher.Query<T> | |
params?: any | |
config?: FetchConfig | |
} | |
const withStaticQuery = function <T>({ query, params, config: { loadOnRefetch = true, fetchTotal = false } = {} }: QueryParams<T>): QueryInfo<T> { | |
const [fetchError, setfetchError] = useState<Meteor.Error | null>(null); | |
const [isLoading, setIsLoading] = useState<boolean>(true); | |
const [data, setData] = useState<T[]>([]); | |
const [count, setCount] = useState<number | undefined>(undefined); | |
const depends = Object.values(params); | |
const { limit, skip, ...paramsWithoutPagination } = params; | |
const newQuery = useMemo(() => { return query.clone(params); }, depends); | |
const countQuery = useMemo(() => { return query.clone(paramsWithoutPagination); }, depends); | |
const fetch = async (): Promise<void> => { | |
let data; | |
let count; | |
try { | |
data = await newQuery.fetchSync(); | |
if (fetchTotal) { | |
count = await countQuery.getCountSync(); | |
} | |
setData(data); | |
setCount(count); | |
setfetchError(null); | |
} catch (error) { | |
setData([]); | |
setfetchError(error); | |
setCount(undefined); | |
} finally { | |
setIsLoading(false); | |
} | |
}; | |
const refetch = (): void => { | |
if (loadOnRefetch) { | |
setIsLoading(true); | |
} | |
void fetch(); | |
}; | |
useEffect(() => { | |
setfetchError(null); | |
setIsLoading(true); | |
void fetch(); | |
}, depends); | |
return { | |
loading: isLoading, | |
refetch, | |
data, | |
count, | |
error: fetchError, | |
}; | |
}; | |
export default withStaticQuery; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment