3

As shown below I'm getting my data in my nextJS application in the pages/article.js using a graphQL query. This data is passed down to another react component, which gives me a list of checkboxes.

Selecting a checkbox is calling a mutation to store the ID of the selected checkboxes in the DB. To get the content updated, I'm using refetchQueries to call the main query again, which will pass the data down to the current component.

So far everything is working. Now I would like to get this stuff realtime using optimistic UI - which makes me some problems...

Replacing the refetchQueries with

update: (store, { data: { getArticle } }) => {
  const data = store.readQuery({
    query: getArticle,
    variables: {
      id: mainID
    }
  })
  console.log(data)
}

runs me to the error TypeError: Cannot read property 'kind' of undefined which comes from readQuery.

I don't see what I'm doing wrong. And this is just the first part to get optimisic UI..

pages/article.js

import Article from '../components/Article'

class ArticlePage extends Component {
  static async getInitialProps (context, apolloClient) {
    const { query: { id }, req } = context
    const initProps = { }

    // ...

    return { id, ...initProps }
  }

  render () {
    const { id, data } = this.props
    const { list } = data
    return (
      <Article
        mainID={id}
        list={list}
      />
    )
  }
}

export default compose(
  withData,
  graphql(getArticle, {
    options: props => ({
      variables: {
        id: props.id
      }
    })
  })
)(ExtendedArticlePage)

components/Article.js

import { getArticle } from '../graphql/article'
import { selectMutation } from '../graphql/selection'

export class Article extends Component {
  checkboxToggle (id) {
    const { mainID, checkboxSelect } = this.props

    checkboxSelect({
      variables: {
        id
      },
      refetchQueries: [{
        query: getArticle,
        variables: {
          id: mainID
        }
      }],

    })
  }

  render () {
    const { list } = this.props
    return (
      list.map(l => {
        return (<Checkbox onClick={this.checkboxToggle.bind(this, l.id)} label={l.content} />)
      }
    )
  }
}

export default compose(
  graphql(selectMutation, { name: 'checkboxSelect' })
)(Article)
user3142695
  • 15,844
  • 47
  • 176
  • 332

1 Answers1

0

You have a variable shadowing issue in your update code, it seems that you're using the same name getArticle for both your query and the mutation result nested in data.

This is why your call to readQuery fails, the query params you need to provide resolves to the mutation result and not the actual query, hence the TypeError: Cannot read property 'kind' of undefined.

You just need to name your query with another identifier like getQueryArticle.

saimeunt
  • 22,666
  • 2
  • 56
  • 61
  • Oh, understand. Thank you for that. Could you please explain the second parameter of the new update function? (`{ data: { getArticle } }`). This seems to have no content in my case, so I think it is named wrong and I'm asking myself if I do really need it... – user3142695 Feb 23 '18 at 12:33
  • Sure you can debug it yourself rewriting your update func like this: `update: (store, { data }) => { console.log(data); }` You'll figure out that there's a field in the data object usually named after your mutation that contains the mutation result. – saimeunt Feb 23 '18 at 13:48