import React from 'react'
import { Query } from 'react-apollo'
import gql from 'graphql-tag'
export const RITES_QUERY = gql`
query RitesQuery($personName: String){
rites(personName: $personName){
createdAt
title
amount
quantity
deposits{
amount
comment
}
}
}
`
const VARIABLES = { personName: "김명자" }
class QueryControl extends React.Component {
render() {
const { children, query } = this.props;
return (
<Query query={query} variables={VARIABLES}>
{({ loading, error, data }) => {
if (loading) return <div>Fetching</div>
if (error) return <div>Error</div>
return (
<React.Fragment>
{children(data)}
</React.Fragment>
)
}}
</Query>
)
}
}
export default QueryControl
Query.ts
async rites(parent, args, ctx: Context) {
const { personName } = args;
if (personName) {
const personExists = await ctx.prisma.$exists.person({
name: personName,
})
if (!personExists) {
throw new Error(`No person exists with name: ${personName}`)
}
const rites = await ctx.prisma.rites({
where: {
person: {
name: personName,
}
}
})
if (rites.length === 0) {
throw new Error(`Empty rites`)
}
return rites
}
return ctx.prisma.rites({ ...args })
}
schema.graphql
type Query {
rites(personName: String): [Rite!]!
}
pollInterval={500}
Polling is an excellent way to achieve near-realtime data without the complexity of setting up GraphQL subscriptions.
<Query
query={RITES_QUERY}
variables={{ personName: selectedPerson.name }}
fetchPolicy={'cache-and-network'}
>
<Query
query={RITES_QUERY}
variables={{ personName: selectedPerson.name }}
fetchPolicy={'cache-and-network'}
>
{({ loading, error, data, refetch, networkStatus }) => {
// if (loading) return <div>Fetching</div>
if (error) return <div>Error {JSON.stringify(error)}</div>
const { rites } = data;
return (<div>
{loading && <div>Fetching</div>}
{rites && rites.map((rite, index) => (
<React.Fragment key={index}>
<RiteTable rite={rite} />
<div style={{ height: "20px" }} />
</React.Fragment>
))}
</div>)
}}
</Query>
Explain
loading
props as returing <div>Fetching</div>
right away
use loading
inside of main return
statement where I can show the cached data while showing fetching status too!returing error from backend service like below
const rites = await ctx.prisma.rites({
where: {
person: {
name: personName,
}
}
})
if (rites.length === 0) {
throw new Error(`Empty rites by the name of ${personName} time: ${Date.now()}`)
}
makes a problem with caching for <Query/>
component in frontend so it is better just returning without Error when it is like minor error stuation such as emtpy result and deal with it in frontend to show the proper result
declare
import { Context } from '../utils'
export const Reportable = {
__resolveType: (reportable, ctx: Context, info) => {
const { category } = reportable
if(category === "불사금"){
return 'Bulsageum'
}
if(category === "지출"){
return 'Expense'
}
if(category === "보시금"){
return 'Bosigeum'
}
return null
},
}
in query
import { Context } from '../../utils'
export const reportables = async (parent, args, ctx: Context) => {
const expenses = await ctx.prisma.expenses()
const bulsageums = await ctx.prisma.bulsageums()
const bosigeums = await ctx.prisma.bosigeums()
let merged = [...expenses, ...bulsageums, ...bosigeums]
merged.sort((a, b) => {
return Date.parse(b.createdAt) - Date.parse(a.createdAt)
})
return merged
}