HowardJohn
HowardJohn

Reputation: 51

React Native, For Loop shows only the first Array Element

I have this function which supposed to loop through 20 elements of (smn) Array to show the elements that meets the IF condition, with this code I got only the first array elements:

    renderSMN() {
    const smn = ['fb', 'twt', 'snp', 'ins', 'ytu', 'lnk', 'tik', 'beh', 'pin', 'tmp', 'www', 'eml', 'wap', 'msg', 'tlg', 'lin', 'wch', 'skp', 'snd', 'oth'];
    for (let i = 0; i < 20; i++) {
        //alert(this.state.data.smu_+smn[i]);
        alert(i);
        if (this.state.data.smu_+smn[i] != "") {
            return (
                <View style={{ margin: 5 }}>
                    <TouchableOpacity onPress={() => {
                        this.props.navigation.navigate('Result', { postId: item.uid, otherParam: 'Pass whatever you want here', });
                    }}>
                        <Image source={{ uri: 'http://localhost/rest/smn/' + smn[i] + '.png' }} style={{ width: 100, height: 100, right: 0, }} />
                    </TouchableOpacity>
                <Text>{i}</Text>
                </View>
            );
        }

This how I get the Data from JSON file:

        fetch('http://localhost/rest/api/single_read.php/?id=' + postId, {
        method: 'GET'
    })
        .then((response) => response.json())
        .then((responseJson) => {
            console.log(responseJson);
            this.setState({
                data: responseJson
            })
        })
        .catch((error) => {
            console.error(error);
        });

Upvotes: 0

Views: 608

Answers (2)

Ivan Rubinson
Ivan Rubinson

Reputation: 3361

Looks like you're exiting the loop early by returning the JSX on the first smn that matches the condition. What you may want to do instead is to return an array of JSXes, some of them being falsy. You can do this by maping the smns to JSX. Note that when working with arrays of JSX, it's recommended to explicitly pass a key prop to each array element's root element.

renderSMN() {
    const smn = ['fb', 'twt', 'snp', 'ins', 'ytu', 'lnk', 'tik', 'beh', 'pin', 'tmp', 'www', 'eml', 'wap', 'msg', 'tlg', 'lin', 'wch', 'skp', 'snd', 'oth'];
    return smn.map((s, i) => {
        alert(i);
        if (this.state.data.smu_+s != "") {
            return (
                <View style={{ margin: 5 }} key={i}>
                    <TouchableOpacity
                        onPress={() => {
                        this.props.navigation.navigate('Result', { postId: item.uid, otherParam: 'Pass whatever you want here', });
                        }}
                    >
                        <Image source={{ uri: 'http://localhost/rest/smn/' + s + '.png' }} style={{ width: 100, height: 100, right: 0, }} />
                    </TouchableOpacity>
                    <Text>{i}</Text>
                </View>
            );
        }
    });
}

Note that if the condition doesn't hold, the function returns undefined implicitly, which is falsy.

Upvotes: 1

lkroneman
lkroneman

Reputation: 106

In the first iteration you return from the renderSMN without continuing the loop.

I'd advise doing something like.

return smn.map(smnItem => {
    if(this.state.data.smu_+smnItem !== '') {
        return (...)
    } 

    return null;
});

instead of the for loop. Which allows to to still use the return keyword

You'd want to replace instances of smn[i] with smnItem

Upvotes: 0

Related Questions