2

I'm using React and fetch() to develop an UI and I ended up doing this:

getOperatorsList: function ( obj ) {
    fetch( 'http://x.x.x.x/operators.list',
        {
            method: 'GET',
            credentials: 'include'
        }
    ).then( function ( response ) {
            return response.json()
        } ).then( function ( json ) {
        if ( json.statusCode === 3 ) {
            cookieService.unsetCookie( 'sessId' );
        }
        obj.setState( { data: json }, () => obj.forceUpdate() );
    } ).catch( function ( ex ) {
        console.log( 'parsing failed', ex );
    } )

}

This is called in my component Operators that looks like this

var Operators = React.createClass( {

    getInitialState: function () {
        return {
            data: [{ "data": "Loading" }]
        }
    },

    componentDidMount: function () {
        operatorsService.getOperatorsList( this );
    },

    render: function () {
        return (
            <div>
                <Row >
                    <Col>
                        <DataTablesCustom data={this.state.data} />
                    </Col>
                </Row>
            </div>
         );
     }
});

I already had a look at this question, and the code doesn't work for me.

This works fine but do I really need to use forceUpdate() or do I have a way to make the code "cleaner" ?

EDIT: there was a setState that looked like this this.setState({stuff: stuff}, this.function()}); in a child component. I was able to remove forceUpdate() after changing the setState to this.setState({stuff: stuff}, () => this.function()});.

7
  • It works without ? Commented Oct 12, 2016 at 14:47
  • Without it, the data i want is not showing when the page loads. Commented Oct 12, 2016 at 14:51
  • So you have your answer, you must use it ;) (this code looks clear for me) Commented Oct 12, 2016 at 14:53
  • This is mostly about how the ReactJS doc says that forceUpdate() should be avoided but i wanted another point of view. thanks :) Commented Oct 12, 2016 at 14:57
  • @Steeve Pitis that code does not look clean at all. Also, he doesn't really have to call forceUpdate at all if he restructure his code a bit better. Commented Oct 12, 2016 at 15:10

1 Answer 1

0

To get your code to work, you can try to do this in the service:

obj.setState.bind(obj)( { data: json });

However, there is no need to pass the component object to your service. Arguably, that's not such a good idea as you're just coupling things when it's not needed. Let the component call your service and then decide what to do with the data:

 getOperatorsList: function () {
    return fetch( 'http://x.x.x.x/operators.list', {
        method: 'GET',
        credentials: 'include'
    }).then( function ( response ) {
        return response.json()
    }).then( function ( json ) {
        if (json.statusCode === 3 ) {
            cookieService.unsetCookie( 'sessId' );
        }
        return json;
    }).catch( function ( ex ) {
      console.log( 'parsing failed', ex );
    })

}

Then in your component:

componentDidMount: function () {
    operatorsService.getOperatorsList()
    .then(function (json) {
       this.setState({ data: json });
    }.bind(this))
}
Sign up to request clarification or add additional context in comments.

6 Comments

You forgot to return the promise in getOperatorsList
I'm getting 'Uncaught TypeError: Cannot read property 'then' of undefined' and the question i quoted did this plus added a return before fetch() but this doesn't work either. i'm getting the same behaviour as before.
@Harmeko sorry, I just forgot to return the promises, I updated getOperatorsList with the return statement.
It still doesn't work. I really don't understand what's wrong. And there's more, when i tried to console.log(this); inside your then() and look at the state, there's data in it but not if i console.log(this.state.data).
@Harmeko from the React docs: facebook.github.io/react/docs/component-api.html "setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value." That's why console.log(this.state) doesn't show you the data. If it still doesn't work, please try to debug/ console.log(this.state.data) in render and see what happens.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.