Bug when trying to make use of .includes

Viewed 145

I'm experiencing the following Bug when I'm trying to define what to return inside the request from axios.

This is my code:

async fetchTask() {
        const token = await AsyncStorage.getItem('access');
        const access = 'Bearer ' + token;
        axios.get(`https://example.com/api/auth/tasl/${this.props.navigation.getParam('id')}`, {
            headers: {
                'Authorization': access,
            }
        })
            .then(res => {
                const id = res.data.id;
                this.setState({ userid: id });
                this.setState({ subject: res.data.subject })
                this.setState({ task: res.data.task })
                this.setState({ image: res.data.task.image })
                this.setState({ progresses: res.data.progresses })
                this.setState({ dueDate: res.data.task.duedate })
                this.setState({ progressValue: res.data.progressValue })
                this.setState({ loading: false });
                if (res.data.task.completed == 1) {
                    this.setState({ isCompleted: true });
                }
                if(this.state.image.includes('http')){
                    converted = this.state.image;
                } else {
                    converted = `https://example.com/storage/${this.state.image}`;
                }
            }).catch(error => {
                this.props.navigation.goBack()
            })
    }

Why is this happening? The image is changed once I click any button.

<Image
   style={{ height: 300, borderRadius: 15 }}
   source={{ uri: converted}}
/>
2 Answers

then callback will look like this,

then((res) => {
let data = res.data;
let stateData = {
    userid: data.id,
    subject: data.subject,
    task: data.task,
    image: data.task.image,
    progresses: data.progresses,
    dueDate: data.task.dueDate,
    progressValue: data.progressValue,
    loading: false,
};

if (res.data.task.completed == 1) {
    stateData["isCompleted"] = true;
}
if (!data.task.image.includes("http")) {
    let converted = `https://example.com/storage/${data.task.image}`;
    stateData["image"] = converted;
}
this.setState(stateData);
});

now you can access image via state like this,

<Image
 style={{ height: 300, borderRadius: 15 }}
 source={{ uri: this.state.image}}
/>

Don't update state for every entry. Otherwise your render will be triggered multiple times.

In the code I also added the conditional operator (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) for in my opinion some cleaner code.

async fetchTask() {
    const token = await AsyncStorage.getItem('access');
    const access = 'Bearer ' + token;

    axios.get(`https://example.com/api/auth/tasl/${this.props.navigation.getParam('id')}`, {
        headers: {
            'Authorization': access,
        }
    })
        .then(res => {
            this.setState({
                userid: data.id,
                subject: data.subject,
                task: data.task,
                progresses: data.progresses,
                dueDate: data.task.dueDate,
                progressValue: data.progressValue,
                loading: false,
                stateData["isCompleted"]: res.data.task.completed == 1,
                image: !data.task.image.includes("http") ? `https://example.com/storage/${data.task.image}` : data.task.image,
            });

        }).catch(error => {
            this.props.navigation.goBack()
        })
}

In the render() you can add something like this:

const { image } = this.state;

{<Image
    style={{ height: 300, borderRadius: 15 }}
    source={{ uri: image }}
/> 

Related