1

Hey all would love some help will this question.. I have been tearing my hair out!

I'm trying to render a ListView using an array of objects of the form:

Array[number]
 0: Object
  category: ''
  date: ''
  total: ''
  vendor: ''
 1: Object ..etc.

I am using the component react-native-swipe-list-view found here: swipeList github

But I'm only rendering the last element of my array of data objects! I'm also using redux in this react-native application although I don't see this having any effect HELP ! :)

Output is as follows enter image description here

Here is my current code.

import React, {
    Component,
} from 'react';
import {
    ListView,
    Text,
    TouchableOpacity,
    TouchableHighlight,
    View,
  Alert
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { SwipeListView } from 'react-native-swipe-list-view';
import {
  PRIMARY_HIGHLIGHT_COLOUR,
  CARD_BACKGROUND_COLOUR,
  BORDER_COLOUR
 } from '../global/colours';
import {
  MySearchBar,
  Button,
  FAB,
  BackgroundView,
 } from '../components';
 import { HEADER } from '../global/margins';

class ReceiptsListView extends Component {

    constructor(props) {
        super(props);
        console.log(this.props.receiptList);
        this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        this.state = {
            listViewData: this.ds.cloneWithRows(this.props.receiptList)
        };
        console.log('state', this.state);
    }


/*  shouldComponentUpdate(nextProps) {
    if (this.props !== nextProps) {
      return true;
    }
    return false;
  } */

    deleteRow(secId, rowId, rowMap) {
    //  rowMap[`${secId}${rowId}`].closeRow();
    //console.log('delete', secId, rowId, rowMap);

    //  const newData = [...this.state.listViewData];
    //  newData.splice(rowId, 1);
    //  this.setState({ listViewData: newData });
    }

    render() {
        //const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        //const dataSource = ds.cloneWithRows(receiptlist);
        //this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        return (
            <BackgroundView style={styles.container}>
                <View style={styles.search}>
                    <MySearchBar />
                    <Button style={styles.button}> Export </Button>
                </View>
                <SwipeListView
                        dataSource={this.state.listViewData}
                        renderRow={(data) => this.renderRow(data)}
                        renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)}
                        rightOpenValue={-150}
                        recalculateHiddenLayout
                        previewFirstRow
                />
                <FAB
            onPress={this.onPressFAB}
                />
            </BackgroundView>
        );
    }

renderRow(data) {
        console.log('data', data);
        return (
            <TouchableHighlight
                onPress={console.log('You touched me')}
                style={styles.rowFront}
                underlayColor={'#AAA'}
            >
                <View>
                    <View style={{ flexDirection: 'row', justifyContent: 'space-between' }} >
                        <Text> {`${data.vendor}`} </Text>
                        <Text> {`${data.total}`} </Text>
                    </View>
                    <View>
                        <Text> {`${data.date}`} </Text>
                        <Text> {`${data.category}`} </Text>
                    </View>
                </View>
            </TouchableHighlight>
        );
    }

    renderHiddenRow(secId, rowId, rowMap) {
        return (
        <View style={styles.rowBack}>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnLeft]}
                onPress={_ => (console.log(secId, rowId, rowMap))}
            >
                <Text style={styles.backTextWhite}>Export</Text>
            </TouchableOpacity>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnRight]}
                onPress={_ => (console.log(secId, rowId, rowMap))}
            >
                <Text style={styles.backTextWhite}>Delete</Text>
            </TouchableOpacity>
        </View>
        );
    }

  onPressFAB() {
    console.log('FAB pressed');
    Alert.alert(
      'Choose Photo Source',
      null,
      [
        { text: 'Camera', onPress: () => Actions.camera() },
        { text: 'Photo Library', onPress: () => Actions.photos() },
        { text: 'Cancel', onPress: () => console.log('cancel'), style: 'cancel' }
      ]
    );
  }
}

const styles = {
  search: {
    flexDirection: 'row',
    padding: 10,
    height: 60,
    backgroundColor: PRIMARY_HIGHLIGHT_COLOUR
  },
  button: {
    marginTop: 0,
    height: 30,
    flexGrow: 0.3
  },
    container: {
    padding: 0,
    paddingTop: HEADER.height
    },
    rowFront: {
        //alignItems: 'center',
    flex: 1,
    padding: 10,
        backgroundColor: CARD_BACKGROUND_COLOUR,
        borderBottomColor: BORDER_COLOUR,
        borderBottomWidth: 1,
        justifyContent: 'center',
        //height: 100,
    },
    rowBack: {
        alignItems: 'center',
        backgroundColor: '#DDD',
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        paddingLeft: 15,
    },
    backRightBtn: {
        alignItems: 'center',
        bottom: 0,
        justifyContent: 'center',
        position: 'absolute',
        top: 0,
        width: 75
    },
    backRightBtnLeft: {
        backgroundColor: 'blue',
        right: 75
    },
    backRightBtnRight: {
        backgroundColor: 'red',
        right: 0
    },
    controls: {
        alignItems: 'center',
        marginBottom: 30
    },
    switchContainer: {
        flexDirection: 'row',
        justifyContent: 'center',
        marginBottom: 5
    },
    switch: {
        alignItems: 'center',
        borderWidth: 1,
        borderColor: 'black',
        paddingVertical: 10,
        width: 100,
    }
};

const mapStateToProps = ({ receipts, accounts }) => {
  const {
    myReceipts,
        receiptList
  } = receipts;
  const {
    labelsArray
  } = accounts;
  return {
    myReceipts,
    receiptList,
    labelsArray
  };
};

export default connect(mapStateToProps, {
})(ReceiptsListView);
3
  • 1
    How did you fixed the issue? I have a similar one, would you mind answering your own question? Commented Mar 7, 2017 at 13:54
  • 1
    My first suggestion would be to use the <SwipeRow> component provided in the same library and use the built in ListView and see if that works better for you. Commented Mar 8, 2017 at 0:15
  • Also why is this downvoted. It's a question with all code shown. Might as well delete the whole thing so noone else can benefit from it thanks to a few asshats. Will be deleting tomorrow if you wanted to copy it Enie Commented Mar 9, 2017 at 9:25

1 Answer 1

5

the issue was the flex:1 in styling of the renderRow (styles. rowFront)

Below is the working code as I'm sure it can be helpful to others.

import React, {
    Component,
} from 'react';
import {
    ListView,
    Text,
    TouchableOpacity,
    TouchableHighlight,
    View,
  Alert,
    TextInput
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { SwipeListView } from 'react-native-swipe-list-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import Spinner from 'react-native-loading-spinner-overlay';

import {
  PRIMARY_HIGHLIGHT_COLOUR,
  CARD_BACKGROUND_COLOUR,
  BORDER_COLOUR,
    SHADOW_COLOUR
 } from '../global/colours';
import {
  Button,
  FAB,
  BackgroundView,
    TitleText
 } from '../components';
 import { HEADER } from '../global/margins';
 import { searchTextChanged, deleteReceipt } from '../actions';

class ReceiptsListView extends Component {

    constructor(props) {
        super(props);
        console.log(this.props.receiptList);
        console.log(this.props.categories);
        this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    }

  shouldComponentUpdate(nextProps) {
    if (this.props !== nextProps) {
      return true;
    } else if (this.props.searchQuery !== nextProps.searchQuery) {
            return true;
        }
    return false;
  }

    render() {
        if (this.props.receiptList.length < 1) {
            return (
                <BackgroundView style={styles.emptyContainer}>
                    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
                        <TitleText> No Receipts </TitleText>
                    </View>
                    <FAB
                        onPress={this.onPressFAB}
                    />
                </BackgroundView>
            );
        }
        return (
            <BackgroundView style={styles.container}>
                <View style={styles.search}>
                        <View style={{ flexGrow: 1, height: 35, paddingTop: 5 }}>
                            <View style={styles.searchStyle}>
                                <View style={styles.searchbar}>
                                    <Icon
                                        name="search"
                                        size={15}
                                        color="#ddd"
                                    />
                                    <TextInput
                                        style={{ flexGrow: 1, width: null, paddingLeft: 5 }}
                                        placeholder='search'
                                        placeholderTextColor='lightgray'
                                        onChangeText={this.onSearchChange.bind(this)}
                                        value={this.props.searchQuery}
                                        onFocus={() => console.log('hi')}
                                    />
                                </View>
                            </View>
                        </View>
                        <Button
                            style={styles.button}
                            //onPress={this.searchText()}
                        >
                            Search
                        </Button>
                    </View>
                <SwipeListView
                        dataSource={this.ds.cloneWithRows(this.props.receiptList)}
                        renderRow={(data) => this.renderRow(data)}
                        renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)}
                        rightOpenValue={-150}
                        recalculateHiddenLayout
                        previewFirstRow
                />
                <FAB
            onPress={this.onPressFAB}
                />
                <Spinner
                    visible={this.props.isFetching}
                    textContent={''}
                    textStyle={{ color: 'white' }}
                />
            </BackgroundView>
        );
    }

    onSearchChange(text) {
        this.props.searchTextChanged(text);
    }

    renderRow(data) {
        //console.log('data', data);
        return (
                <TouchableHighlight
                    onPress={() => console.log('You touched me', data)}
                    underlayColor={'#AAA'}
                    style={styles.rowFront}
                >
                    <View>
                        <View style={{ flexDirection: 'row', justifyContent: 'space-between' }} >
                            <Text> {`${data.vendor}`} </Text>
                            <Text> {`${data.total}`} </Text>
                        </View>
                        <View>
                            <Text> {`${data.date}`} </Text>
                            <Text> {`${data.category}`} </Text>
                        </View>
                    </View>
                </TouchableHighlight>
        );
    }

    renderHiddenRow(secId, rowId, rowMap) {
        return (
        <View style={styles.rowBack}>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnLeft]}
                onPress={() => (this.exportItem(secId, rowId, rowMap))}
            >
                <Text style={styles.backTextWhite}>Export</Text>
            </TouchableOpacity>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnRight]}
                onPress={() => (this.deleteItem(secId, rowId, rowMap))}
            >
                <Text style={styles.backTextWhite}>Delete</Text>
            </TouchableOpacity>
        </View>
        );
    }

    deleteItem(secId, rowId, rowMap) {
        console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap);
        console.log('obj', secId.id, 'acc', this.props.curAccountID);
        this.props.deleteReceipt(this.props.curAccountID, secId.id);
    }

    exportItem(secId, rowId, rowMap) {
        console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap);
        //this.props.exportReceipt(this.props.curAccountID, secId.id);
    }

  onPressFAB() {
    console.log('FAB pressed');
    Alert.alert(
      'Choose Photo Source',
      null,
      [
        { text: 'Camera', onPress: () => Actions.camera() },
        { text: 'Photo Library', onPress: () => Actions.photos() },
        { text: 'Cancel', onPress: () => console.log('cancel'), style: 'cancel' }
      ]
    );
  }
}

const styles = {
  search: {
    flexDirection: 'row',
    padding: 10,
    height: 60,
    backgroundColor: PRIMARY_HIGHLIGHT_COLOUR
  },
    searchbar: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        paddingLeft: 5
    },
  button: {
    marginTop: 0,
    height: 30,
    flexGrow: 0.3
  },
    container: {
    padding: 0,
    paddingTop: HEADER.height
    },
    emptyContainer: {
        flex: 1,
        padding: 0,
        paddingTop: HEADER.height,
        justifyContent: 'center'
    },
    rowFront: {
        //alignItems: 'center',
    padding: 10,
        backgroundColor: CARD_BACKGROUND_COLOUR,
        borderBottomColor: BORDER_COLOUR,
        borderBottomWidth: 1,
        justifyContent: 'center',
        //height: 100,
    },
    rowBack: {
        alignItems: 'center',
        backgroundColor: '#DDD',
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        paddingLeft: 15,
    },
    backRightBtn: {
        alignItems: 'center',
        bottom: 0,
        justifyContent: 'center',
        position: 'absolute',
        top: 0,
        width: 75
    },
    backRightBtnLeft: {
        backgroundColor: 'blue',
        right: 75
    },
    backRightBtnRight: {
        backgroundColor: 'red',
        right: 0
    },
    controls: {
        alignItems: 'center',
        marginBottom: 30
    },
    switchContainer: {
        flexDirection: 'row',
        justifyContent: 'center',
        marginBottom: 5
    },
    switch: {
        alignItems: 'center',
        borderWidth: 1,
        borderColor: 'black',
        paddingVertical: 10,
        width: 100,
    },
    searchStyle: {
        flex: 1,
        flexDirection: 'row',
        alignSelf: 'stretch',
        padding: 5,
        justifyContent: 'flex-start',
        alignItems: 'center',
        backgroundColor: CARD_BACKGROUND_COLOUR,
        borderRadius: 10,
        borderWidth: 1,
        borderColor: 'grey',
        marginLeft: 5,
        marginRight: 5,
        shadowColor: SHADOW_COLOUR,
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 2,
    },
};

const mapStateToProps = ({ accounts, receipts, searchIt }) => {
    const {
        curAccountID
    } = accounts;
    const {
        searchQuery
    } = searchIt;
  const {
        isFetching,
    myReceipts,
        receiptList,
        categories
  } = receipts;
  return {
        curAccountID,
        isFetching,
    myReceipts,
        receiptList,
        searchQuery,
        categories
  };
};

export default connect(mapStateToProps, {
        searchTextChanged, deleteReceipt
})(ReceiptsListView);
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. It is exactly the thing I had too, it fixed my issue.
@Ally Haire Thanks for the answer. I upvoted ur question and gave it a star.
can you give link of other reference like component,action,color etc
@rajesh I'm not sure I understand your question?
i am new in react native. i need following dependency from '../global/colours'; import { Button, FAB, BackgroundView, TitleText } from '../components'; import { HEADER } from '../global/margins'; import { searchTextChanged, deleteReceipt } from '../actions';

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.