Search code examples
graphqlrelayjsrelaygraphql-js

Relay requests via setVariables


when a request is made via setVariables is there a way to take account of the local state in-between async requests i.e. to implement loading indicator ?

an illustration making requests to https://www.graphqlHub.com/graphql

  _onChange = (ev) => {
    this.setState({
      loading:true
    })
    let gifType = ev.target.value;
    this.props.relay.setVariables({
      gifType
    });
    this.setState({
      loading:false
    })
  }

this won't track the loading state and loading will pass on to false immediately while the async change to the view will have lag.

if we move loading into setVariables is there any way to track the response ? in the root container there is the ability to track response via

  renderLoading={function() {
    return <div>Loading...</div>;
  }}

is there any similar method for Relay.createContainer

is it bad practice to use setVariables to navigate through data sets ?

full code

class GiphItems extends React.Component {
  constructor(){
    super();
    this.state = {
      loading: false
    }
  }
  render() {
    const random = this.props.store.random
    return <div>
      <select onChange={this._onChange.bind(this)} value={this.props.relay.variables.gifType}>
        <option value="sexy">Sexy</option>
        <option value="cats">Cats</option>
        <option value="goal">Goal</option>
        <option value="lol">LOL</option>
      </select>
      {this.state.loading ? 'LOADING' : <a href={random.url}><img src={random.images.original.url} className="img-responsive"/></a>}
    </div>;
  }

  _onChange = (ev) => {
    this.setState({
      loading:true
    })
    let gifType = ev.target.value;
    this.props.relay.setVariables({
      gifType
    });
    this.setState({
      loading:false
    })
  }
}
GiphItems = Relay.createContainer(GiphItems, {
  initialVariables: {
    gifType: "sexy"
  },
  fragments: {
    store: () => Relay.QL`
      fragment on GiphyAPI {
        random(tag: $gifType ) {
            id
            url
            images {
              original {
                url
              }
            }
            }
      }
    `,
  },
});

Solution

  • setVariables method also accepts a callback as the 2nd argument which responds to the events involved with the data fulfillment and it receives a 'readyState' object that you can inspect:

    this.props.relay.setVariables({
            gifType,
          }, (readyState)=> {
            if (!readyState.done) {
              this.setState({
                loading: true
              })
            } else if(readyState.done) {
              this.setState({
                loading: false
              })
            }
    })