Search code examples
javascriptreact-nativees6-promisefetch-api

How to catch the network error while fetching the error in promise


So I have this Picker component, and for the items, I am fetching the data from the server and mapping it when the state is changed.

//api.js
var api = {
    getBooks() {
        var url = 'http://192.168.43.14:8080/api/books/'
        var headers = new Headers();
        headers.append('Accept', 'application/json');
        return fetch(url, headers)
            .then((res) => res.json())  
            .catch(function(err) {  
                console.log('Fetch Error :-S', err);
                throw Error(err);
            });
    }
}

//RegisterMobile.js
import api from '../utilities/api'

export default class RegisterMobile extends Component {
    constructor(props) {
        super(props)
        this.state = {
            books: [],
            book: '',
            mobile: '',
            displayError: false,
            error: 'Please provide a valid mobile number'
        }
    }

    componentWillMount() {
        api.getBooks().then((res) => {
            this.setState({
                books: res
            })
        })
    }

    render() {
        return(
            <View>
                <View style={styles.selecBook}>
                    <Picker selectedValue={this.state.book} onValueChange={this.changeBook}>
                        {this.state.books.map((book) => {return <Picker.Item value={book.name} label={book.name} key={book.id}  />})}
                    </Picker>
                </View>
                {this.state.displayError ? <Text style={styles.error}>{this.state.error}</Text> : null}
            </View>
        )
    }
}

This is working fine. I get the list of items and when I click on the Picker, I can select the items. What I want to do is, if there was any error while fetching the data (eg. server is down), I would like to get that error and display it as error (which would be just changing the state of error and displayError). But I don't know how to get the error if there was one to set it in the state of the error.


Solution

  • Don't catch the error inside the api. Do it where you want to use the result of the async operation. Something like this...

    //api.js
    var api = {
        getBooks() {
            var url = 'http://192.168.43.14:8080/api/books/'
            var headers = new Headers();
            headers.append('Accept', 'application/json');
            return fetch(url, headers)
                .then((res) => res.json());
    
        }
    }
    
    //RegisterMobile.js
    import api from '../utilities/api'
    
    export default class RegisterMobile extends Component {
        constructor(props) {
            super(props)
            this.state = {
                books: [],
                book: '',
                mobile: '',
                displayError: false,
                error: 'Please provide a valid mobile number'
            }
        }
    
        componentWillMount() {
            api.getBooks()
               .then((res) => { this.setState({books: res}) })
               .catch(function(err) {  
                    console.log('Fetch Error :-S', err);
                    this.setState({books: [], book: null, displayError: true, error:err});
                });
        }