wogrady1
wogrady1

Reputation: 13

How do you group a list of transactions by the date they're created in react native?

I have a JSON list of test transactions and I'm able to display them with the dates they were performed but I would like to be able to group these so that for instance all transactions that were performed today are listed under one banner that says 'Today' and other transactions that were performed on same dates fall under a banner displaying that date. I've tried to think of ways to implement this but am struggling, any help would be appreciated.

Below is the component I'm trying to create this function within.

import React from 'react';
import {
  Text,
  SafeAreaView,
  StatusBar,
  ActivityIndicator,
  FlatList,
  View,
  List,
  Image,
  SectionList,
} from 'react-native';
import moment from 'moment';
import transactions from '../testdata/transactions.json';
import Icon from 'react-native-ionicons'

var datetest = [moment(transactions[0].addedtime).calendar()];
 
moment.locale('en-uk', {
  calendar: {
    lastDay: '[Yesterday ]',
    sameDay: '[Today]',
    nextDay: '[Tomorrow]',
    lastWeek: 'L',
    nextWeek: 'dddd',
    sameElse: 'L',
  },
});

class TransactionsComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      isLoading: true,
      dataSource: [],
      epochDate: [],
    };
  }

  componentDidMount() {
    this.setState({
      isLoading: false,
      dataSource: transactions,
      epochDate: datetest,
    });
  }

  
  renderSeparator = () => {
    return (
      <View
        style={{
          height: 0,
          width: '100%',
          backgroundColor: '#F5F5F5	',
          marginLeft: '0%',
        }}
      />
    );
  };
  

  render() {
    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, padding: 20}}>
          <ActivityIndicator />
        </View>
      );
    }
  }


 

  render() {
    return (
      <View style={{width: '100%'}}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) => (
            <View
              style={{
                flex: 1,
                flexDirection: 'column',
                borderBottomColor: '#5AA8C8',
                borderBottomWidth: 1,
                paddingBottom: 10,
              }}>

              
              { <View style={{marginLeft: '3%'}}>
                <Text style={{fontWeight: 'bold', fontSize: 18}}>
                  {moment(item.addedtime).calendar()}
                </Text>
              </View> }
              <View style={{marginLeft: '5%', flexDirection: 'row', flex: 2,}}>
                <View
                  style={{flexDirection: 'row', alignItems: 'center', flex: 3}}>
                  <Image
                    style={{width: 40, height: 40}}
                    source={{uri: item.iconblob}}
                  />
                
                  <Text
                    style={{fontSize: 16, color: 'grey', fontWeight: 'bold'}}>
                    {'  '}
                    {item.merchantname}
                  </Text>
                </View>
                <View
                  style={{
                    flex: 1,
                    flexDirection: 'row',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    marginRight: '3%',
                  }}>
                  <Text style={{fontSize: 18, color: 'black'}}>
                    <Text style={{fontSize: 12, color: 'grey'}}>CHF</Text>
                    {parseFloat(item.billingamountauthorised / 100).toFixed(2)}
                   
                  </Text>
                  <View style= {{flex :6, flexDirection:"row", justifyContent:"flex-end"}}>
                    <Icon name="arrow-dropright" color="#5AA8C8" />
                    </View>
                </View>
              </View>
            </View>
          )}
          keyExtractor={item => item.uniqueref}
          //containerStyle={{borderBottomWidth: 0}}
        />
      </View>
    );
  }
}

export default TransactionsComponent;

This is an example of how the JSON looks with addedtime being the epoch date the transaction was created

[   
    {
    "billingamountauthorised": "1",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1576590342000,
    "uniqueref": "A446806878486B5B"
},
{
    "billingamountauthorised": "750",
    "iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
    "merchantname": "Starbucks",
    "merchantstreet": "Rue du Mont-Blanc",
    "addedtime": 1576590342000,
    "uniqueref": "D0868EB65DC2DE585"
},
    {
        "billingamountauthorised": "1",
        "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
        "merchantname": "K Kiosk Sihlquai",
        "merchantstreet": "Sihlquai",
        "addedtime": 1576590342000,
        "uniqueref": "A446806878486B5B0"
    },
    {
        "billingamountauthorised": "100",
        "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
        "merchantname": "K Kiosk Sihlquai",
        "merchantstreet": "Sihlquai",
        "addedtime": 1575554709000,
        "uniqueref": "0D10B5F56A73D73DD"
        
    },
    {
        "billingamountauthorised": "1320",
        "iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
        "merchantname": "Schweizerische Bundesbahnen",
        "merchantstreet": "Bahnhofplatz",
        "addedtime": 1575554709000,
        "uniqueref": "2F3D907B0FF675216"
    }
  ]

This is currently how it is the transactions are looking with each one displaying the date next to it regardless of if the date is the same as another transaction.

Upvotes: 1

Views: 4723

Answers (1)

SDushan
SDushan

Reputation: 4631

If you are planning to use SectionList, you need to group item according to dates. in-order to do that you can used reduce method in JavaScript.

const JSON_DATA = [
  {
    "billingamountauthorised": "1",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1576590342000,
    "uniqueref": "A446806878486B5B"
  },
  {
    "billingamountauthorised": "750",
    "iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
    "merchantname": "Starbucks",
    "merchantstreet": "Rue du Mont-Blanc",
    "addedtime": 1576590342000,
    "uniqueref": "D0868EB65DC2DE585"
  },
  {
    "billingamountauthorised": "1",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1576590342000,
    "uniqueref": "A446806878486B5B0"
  },
  {
    "billingamountauthorised": "100",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1575554709000,
    "uniqueref": "0D10B5F56A73D73DD"

  },
  {
    "billingamountauthorised": "1320",
    "iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
    "merchantname": "Schweizerische Bundesbahnen",
    "merchantstreet": "Bahnhofplatz",
    "addedtime": 1575554709000,
    "uniqueref": "2F3D907B0FF675216"
  }
]

let data = Object.values(JSON_DATA.reduce((acc, item) => {
  if (!acc[item.addedtime]) acc[item.addedtime] = {
    title: item.addedtime,
    data: []
  };
  acc[item.addedtime].data.push(item);
  return acc;
}, {}))

Now you can used React-Native SectionList as below demo.

import React, { Component } from 'react';
import { StyleSheet, Text, View, SectionList, Image } from 'react-native';

const JSON_DATA = [
  {
    "billingamountauthorised": "1",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1576590342000,
    "uniqueref": "A446806878486B5B"
  },
  {
    "billingamountauthorised": "750",
    "iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
    "merchantname": "Starbucks",
    "merchantstreet": "Rue du Mont-Blanc",
    "addedtime": 1576590342000,
    "uniqueref": "D0868EB65DC2DE585"
  },
  {
    "billingamountauthorised": "1",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1576590342000,
    "uniqueref": "A446806878486B5B0"
  },
  {
    "billingamountauthorised": "100",
    "iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
    "merchantname": "K Kiosk Sihlquai",
    "merchantstreet": "Sihlquai",
    "addedtime": 1575554709000,
    "uniqueref": "0D10B5F56A73D73DD"

  },
  {
    "billingamountauthorised": "1320",
    "iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
    "merchantname": "Schweizerische Bundesbahnen",
    "merchantstreet": "Bahnhofplatz",
    "addedtime": 1575554709000,
    "uniqueref": "2F3D907B0FF675216"
  }
]

const DATA = Object.values(JSON_DATA.reduce((acc, item) => {

  if (!acc[item.addedtime]) acc[item.addedtime] = {
    title: item.addedtime,
    data: []
  };
  acc[item.addedtime].data.push(item);
  return acc;

}, {}))


export default class App extends Component {

  renderItems = ({ item }) => {
    return (
      <View style={styles.itemStyle}>
        <Image
          style={{ width: 60, height: 60 }}
          source={{ uri: item.iconblob }}
        />
        <Text>{item.merchantname}</Text>
        <Text>{item.merchantstreet}</Text>
      </View>
    )
  }

  renderHeader = ({ section }) => {
    return (
      <View style={styles.headerStyle}>
        <Text>{section.title}</Text>
      </View>
    )
  }

  render() {
    return (
      <SectionList
        sections={DATA}
        keyExtractor={(item, index) => item + index}
        renderItem={this.renderItems}
        renderSectionHeader={this.renderHeader}
      />
    );
  }

}

const styles = StyleSheet.create({
  itemStyle: {
    backgroundColor: '#dcdee0',
    padding: 10,
    margin: 5,
  },
  headerStyle: {
    paddingLeft: 10,
    paddingVertical: 10,
  },
});

Hope this will help you. try to modify code according to your requirements.

Upvotes: 4

Related Questions