0

This is how I extend my component:

const ComponentWithMutation = graphql(GQL_MUTATION_ACTIVATE, 
    {
        options: (props) => ({
            variables: {
                foo: props.foo,
                bar: props.bar,
            },
        }),
    })(ActivateEmail);

Now inside component:

class ActivateEmail extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        const { match, mutate } = this.props;
        mutate({
            variables: { token: match.params.atoken },
        });
    }

    render() {
        return (
            <div>
                // I need to access data, error, loading here...
            </div>
        );
    }
}

I would like to access data, error, loading. How can I do it in render method?

Pablo
  • 28,133
  • 34
  • 125
  • 215

1 Answers1

0

regarding apollo-client docs, mutation returns a promise that returns mutation information like data, error, loading, etc..

so the codes should look like:

constructor() {
    this.state = {
        dataLoading: true,
        dataLoadError: false,
    }
}

async componentDidMount() {
    try {
        const { match, mutate } = this.props;
        const { data: { yourMutationData }, error} = await mutate({
            variables: { token: match.params.atoken },
        });
        this.setState({
            dataLoading: false,
            data: yourMutationData 
        });
    }
    catch (err) {
        this.setState({
            dataLoading: false,
            dataLoadError: true,
        });
    }
}

or you can use a normal promise like that:

componentDidMount() {
    const { match, mutate } = this.props;
    mutate({
        variables: { token: match.params.atoken },
    })
    .then( (query) => {
        console.log(query); //here you should get the same result with the code above.
        this.setState({
            dataLoading: false,
            data: query.data.yourMutationData 
        });
    })
    .catch(err => {
        this.setState({
            dataLoading: false,
            dataLoadError: true,
        });
    })
}
Muho
  • 3,188
  • 23
  • 34
  • 1
    I am getting an error that constructor can't be async. – Pablo May 05 '19 at 13:13
  • you are right, seems I just modified changed the answer. – Muho May 05 '19 at 13:16
  • 1
    This however makes `loading` unusable. I am not receiving any new `render` call with `loading` true. Only once data is ready, state changed and render is called. loading is always false. – Pablo May 05 '19 at 13:31
  • you seem right, I suggest to set the initial loading state to true in the constructor and set it to false when you handle the success or error from the mutation response, so you can make sure that the loading will stop when the mutation duration finishes. will modify the answer depending on that – Muho May 05 '19 at 13:49
  • This is just simulating partially loading state. User might see "loading" even if he's disconnected from internet for instance. There can be other situations when mimicking loading sate is not right. It's not giving the actual state. – Pablo May 05 '19 at 14:00
  • this is how loading mechanism works with post requests in general, if you notice that we are handling if the mutation fails in catch blocks, so if there is no internet or whatever reason makes that mutation fails, the loading will stop when it fails. – Muho May 05 '19 at 15:02