I've come across a problem working in react native. I've parsed a large JSON object and need to iterate over an array nested inside it. All I need to do is print three values in each item object for day[0].
My code:
import React, { Component, PropTypes } from 'react';
import { View, Text, ListView, StyleSheet, TouchableHighlight} from 'react-native';
import Header from '../Components/Header';
import Api from '../Utility/Api';
export default class CalendarPage extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(
fetch('https://s3.amazonaws.com/cbu-rec-center-app/credentials/schedule.json')
)
};
}
componentWillMount(){
Api.getDates().then((res) => {
this.setState({
//I need to have these three output, but for all items in day[0]
EventName: res.days[0].items[0].summary,
EventDate: res.days[0].items[0].start.dateTime,
EventLocation: res.days[0].items[0].description
})
})
}
render() {
return (
<View style={{flex: 1}}>
<Header pageName="Calendar" navigator={this.props.navigator}/>
<View style = {{flex:9}}>
<Text> {this.state.EventName} </Text>
<Text> {this.state.EventDate} </Text>
<Text> {this.state.EventLocation} </Text>
</View>
</View>
);
}
}
The JSON
"days": [{
"date": "2017-03-06",
"hours": {
"open": "06:00",
"close": "12:00"
},
"items": [{
"kind": "calendar#event",
"etag": "\"2977101842476000\"",
"id": "fhq5hof67nvqhj85qm65t1n3e4",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=ZmhxNWhvZjY3bnZxaGo4NXFtNjV0MW4zZTQgY2J1cmVjcmVhdGlvbmNlbnRlckBt",
"created": "2017-03-03T14:22:01.000Z",
"updated": "2017-03-03T14:22:01.238Z",
"summary": "Women's Volleyball",
"description": "West Court",
"creator": {
"email": "cburecreationcenter#gmail.com",
"displayName": "Cbu RecreationCenter",
"self": true
},
"organizer": {
"email": "cburecreationcenter#gmail.com",
"displayName": "Cbu RecreationCenter",
"self": true
},
"start": {
"dateTime": "2017-03-06T15:30:00-08:00"
},
"end": {
"dateTime": "2017-03-06T16:30:00-08:00"
},
"iCalUID": "fhq5hof67nvqhj85qm65t1n3e4#google.com",
"sequence": 0,
"reminders": {
"useDefault": true
},
"type": "event"
},
{
"kind": "calendar#event",
"etag": "\"2976616094232000\"",
"id": "4tnn4gn0gstndi5idrqjsg7elo_20170306T200000Z",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=NHRubjRnbjBnc3RuZGk1aWRycWpzZzdlbG9fMjAxNzAzMDZUMjAwMDAwWiBrbTVyM2dycW1qbjZiMTQ2MWk2aXBjMjJhc0Bn",
"created": "2017-02-28T14:24:06.000Z",
"updated": "2017-02-28T18:54:07.116Z",
"summary": "Boxing Boot Camp",
"creator": {
"email": "cburecreationcenter#gmail.com",
"displayName": "Cbu RecreationCenter"
},
"organizer": {
"email": "km5r3grqmjn6b1461i6ipc22as#group.calendar.google.com",
"displayName": "Group X Calendar",
"self": true
},
"start": {
"dateTime": "2017-03-06T12:00:00-08:00"
},
"end": {
"dateTime": "2017-03-06T12:45:00-08:00"
},
"recurringEventId": "4tnn4gn0gstndi5idrqjsg7elo",
"originalStartTime": {
"dateTime": "2017-03-06T12:00:00-08:00"
},
"iCalUID": "4tnn4gn0gstndi5idrqjsg7elo#google.com",
"sequence": 0,
"reminders": {
"useDefault": true
},
"type": "class"
},
{
"kind": "calendar#event",
"etag": "\"2967485504076000\"",
"id": "m533eg9bu5o4meinuu7pvfoge4_20170306T210000Z",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=bTUzM2VnOWJ1NW80bWVpbnV1N3B2Zm9nZTRfMjAxNzAzMDZUMjEwMDAwWiBrbTVyM2dycW1qbjZiMTQ2MWk2aXBjMjJhc0Bn",
"created": "2017-01-06T22:45:52.000Z",
"updated": "2017-01-06T22:45:52.038Z",
"summary": "Women on Weights",
"description": "This is a weight lifting class designed to empower women to lift free weights in a group setting . The goals of WOW are to teach proper form, assist women in improving their posture, increasing their strength, and muscle pairing. ",
"location": "Group X Room",
"creator": {
"email": "cburecreationcenter#gmail.com",
"displayName": "Cbu RecreationCenter"
},
"organizer": {
"email": "km5r3grqmjn6b1461i6ipc22as#group.calendar.google.com",
"displayName": "Group X Calendar",
"self": true
},
"start": {
"dateTime": "2017-03-06T13:00:00-08:00",
"timeZone": "America/Los_Angeles"
},
"end": {
"dateTime": "2017-03-06T14:00:00-08:00",
"timeZone": "America/Los_Angeles"
},
"recurringEventId": "m533eg9bu5o4meinuu7pvfoge4",
"originalStartTime": {
"dateTime": "2017-03-06T13:00:00-08:00",
"timeZone": "America/Los_Angeles"
},
"iCalUID": "m533eg9bu5o4meinuu7pvfoge4#google.com",
"sequence": 0,
"reminders": {
"useDefault": true
},
"type": "class"
},
you can do it using .map():
<View>
{ res.days[0].items.map((item) => (
<View>
<Text>{item.summary}</Text>
<Text>{item.start.dateTime}</Text>
<Text>{item.description}</Text>
</View>
))}
</View>
make sure to check for data availability not to display empty <Text> blocks
Related
I want to partition my messages by date for my chat application(Similar to the Microsoft teams app)
The message data will be like
[
{
"id": 577,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "John J"
},
"body": "test test",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T07:59:28.873+00:00"
},
{
"id": 578,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "Don V"
},
"body": "ok",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T08:02:26.262+00:00"
},
{
"id": 628,
"source": {
"userID": 56470,
"profilePictureUrl": "",
"name": "Sam GP"
},
"body": "Hola",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:27:48.038+00:00"
},
{
"id": 629,
"source": {
"userID": 56470,
"profilePictureUrl": "",
"name": "Rawn OP"
},
"body": "ek",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:29:36.705+00:00"
},
{
"id": 630,
"source": {
"userID": 56470,
"profilePictureUrl": "",
"name": "Paul John"
},
"body": "hi",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:30:36.695+00:00"
},
{
"id": 631,
"source": {
"userID": 56470,
"profilePictureUrl": "",
"name": "Dennise V"
},
"body": "knock knock",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:32:38.035+00:00"
},
{
"id": 632,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "Shawn"
},
"body": "who's this",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:37:25.985+00:00"
},
{
"id": 633,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "Pater B"
},
"body": "I see",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:37:30.783+00:00"
},
{
"id": 634,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "Cera LO"
},
"body": "Will call you later",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-20T17:37:38.268+00:00"
},
{
"id": 642,
"source": {
"userID": 56469,
"profilePictureUrl": "",
"name": "Rose BH"
},
"body": "hello???????",
"readStatus": true,
"attachments": null,
"createdDateTime": "2022-09-21T05:25:56.642+00:00"
}
]
I need to arrange these data to show the messages by date like
------------------------------Sep 30-----------------------------
Messages sent/received on sep 30
------------------------------Yesterday--------------------------
Messages sent/received on yesterday
------------------------------Last read-------------------------
------------------------------Oct30-----------------------------
------------------------------Yesterday-------------------------
------------------------------Today-----------------------------
For displaying "Sep 30", "yesterday", and "Today" I've created a pipe that converts the timestamp into the month and "yesterday", "today" etc.
I already got the solution to arrange the message by date. But I have to arrange it under the "Last read" block too. Same as by dates. the flag "readStatus" is sed to check whether the message has been read or not" If it is false is should come under "Last read".
Any ideas? Any help will be appreciated.
I imagine you can has something like (if your data is in a variable "data"
dataOrder = {
readed: this.group(this.data.filter((x) => x.readStatus)),
notReaded: this.group(this.data.filter((x) => !x.readStatus)),
};
group(data: any[]) {
return data.reduce((a, b) => {
const dateTime=new Date(b.createdDateTime.substr(0,10)+"T00:00:00.00+00:00")
.getTime()
const element = a.find((x) => x.dateTime == dateTime);
if (!element) a.push({ dateTime:dateTime,data: [b] });
else element.data.push(b);
return a;
}, []);
}
See that "dataOrder" has two properties "readed" and "notReaded", each one are arrays of objects in the way
{
dateTime:a dateTime,
data:an array with the messages
}
This makes easy indicate the date using Angular date pipe, and loop over the messages
So, an .html like
<h1>Readed</h1>
<ng-container
*ngTemplateOutlet="messagedata; context: { $implicit: dataOrder.readed }"
></ng-container>
<h1>Not Readed</h1>
<ng-container
*ngTemplateOutlet="messagedata; context: { $implicit: dataOrder.notReaded }"
></ng-container>
<ng-template #messagedata let-data>
<div *ngFor="let readed of data">
{{ readed.dateTime | date }}
<div *ngFor="let message of readed.data">
{{ message.createdDateTime }} - {{ message.body }}
</div>
</div>
</ng-template>
I use the same template for both type of messages
A stackblitz
Update As the dataOrder it's only change at fisrt is better use a function
getDataOrdered(data:any[])
{
return {
readed: this.group(data.filter((x) => x.readStatus)),
notReaded: this.group(data.filter((x) => !x.readStatus)),
};
}
Then, we can, each time some message change its "readStatus" we can do
this.dataOrder=this.getDataOrdered(this.data)
I have this object:
{
"id": 24,
"pic": {
"pic": [{
"url": "760634d2-f8ec-4caa-9a2d-14a8828cfb5dpetplace.jpg"
},
{
"url": "760634d2-f8ec-4caa-9a2d-14a8828cfb5dpetplace.jpg"
}
]
},
"title": "Title",
"title_icon": "760634d2-f8ec-4caa-9a2d-14a8828cfb5dpetplace.jpg",
"social_link": {
"social_link": [{
"facebook": "https://facebook.com"
},
{
"instagram": "https://insta.com"
}
]
},
"phone_number": "03246101715",
"address": "346-B PUEHS TOWN 1 BLOCK B",
"lat": "45678",
"long": "45678",
"postcode": "54000",
"start_time": "2021-11-15T12:15:39.658Z",
"end_time": "2021-11-15T12:15:39.658Z",
"email": "Husnain#gmail.com",
"web_url": "https://getbootstrap.com",
"createdAt": "2021-11-15T12:15:39.658Z",
"category": {
"id": 1,
"name": "Resturant",
"pic": "restaurent.png",
"createdAt": "2021-11-16T18:56:51.163Z"
}
},
I want too return the facebook and insta links in a table. I am using a map function to display all the records since there are multiple objects in the array.
{
filteredData.map((product) => (
<Fragment>
{editContactId === product.id ? (
<EditableData data={product} />
) : (
<ReadOnly
data={product}
id={product.id}
handleEditClick={handleEditClick}
/>
)}
</Fragment>
));
}
I have tried this <td>{data.social_link.social_link[0].facebook}</td> but it does not work. Any suggestions?
Am trying to create a shopping cart in react native, my problem is whenever i add a product to the shopping cart it is added through the following action:
export const addToCart = (item) => {
return (dispatch) =>{
dispatch({
type:ADD_TO_CART,
payload: {item}});
}
}
this is the reducer:
import {REMOVE_FROM_CART,ADD_TO_CART,UPDATE_CART_QUANTITY,GET_CATEGORIES, GET_PRODUCTS,
MODAL_STATE,MODAL_STATE_HIDE,ADDRESS_CHANGED,SELECTED_ITEMS} from '../actions/types';
const INITIAL_STATE = {
products:'',
cart:[],
category:'',
isVisible:false,
address:'',
selectedItem:[]
}
export default function(state=INITIAL_STATE, action){
let cart = state.cart;
switch(action.type){
case ADD_TO_CART:
return{...state, cart:[...state.cart, action.payload]}
case REMOVE_FROM_CART:
return{cart:[...state.cart.filter(item => item.id != action.payload)]}
// {...state, cart:[...state.cart.filter((id)=>{ id !== action.payload})]}
case UPDATE_CART_QUANTITY:
return {
...state,
cart: state.cart.map(cart=> cart.id === action.payload.item.id ?
{ ...cart, quantity: action.payload.value} :
cart
)
};
case GET_CATEGORIES:
return{...state, category:action.payload}
case GET_PRODUCTS:
return{...state, products:action.payload}
case MODAL_STATE:
return{...state, isVisible:true}
case MODAL_STATE_HIDE:
return{...state, isVisible:false}
case ADDRESS_CHANGED:
return{...state, address:action.payload}
case SELECTED_ITEMS:
return{...state, selectedItem:[...state.selectedItem, action.payload]}
default:
return state
}
}
BUT when i try to access the cart through mapping state to props in the cart component, it returns undefined is not an object, when console log typeof(cart) from cart component it says its an object:
this is the mapstatetoprops function:
const mapStateToProps = (state) => {
return{
cartItems:state.product_reducer.cart,
modalValue:state.product_reducer.isVisible,
total: state.product_reducer.cart.reduce(
in the array
(accumulatedTotal, cartItem) =>
accumulatedTotal + cartItem.price * cartItem.quantity,
0
)
}
}
this is the json product data that i add to the cart there are two products with 7 and 8 as ids:
{
"product": [
{
"id": 8,
"name": "asad",
"quantity": 1,
"type": "already",
"description": null,
"price": "20000.00",
"ingredients": null,
"deliveryfee": "0.00",
"supplier": null,
"duration": "3",
"category_id": 3,
"created_at": "2020-05-03 15:03:23",
"updated_at": "2020-05-03 15:03:23",
"deleted_at": null,
"photo": {
"id": 19,
"model_type": "App\\Product",
"model_id": 8,
"collection_name": "photo",
"name": "5eaedd370c100_jamies-iced-green-tea",
"file_name": "5eaedd370c100_jamies-iced-green-tea.jpg",
"mime_type": "image/jpeg",
"disk": "public",
"size": 36610,
"manipulations": [],
"custom_properties": {
"generated_conversions": {
"thumb": true
}
},
"responsive_images": [],
"order_column": 19,
"created_at": "2020-05-03 15:03:24",
"updated_at": "2020-05-03 15:03:24",
"url": "http://192.168.0.112/kwenu/storage/app/public/19/5eaedd370c100_jamies-iced-green-tea.jpg",
"thumbnail": "http://192.168.0.112/kwenu/storage/app/public/19/conversions/5eaedd370c100_jamies-iced-green-tea-thumb.jpg"
},
"sliderimages": [],
"tags": [
{
"id": 1,
"name": "Avocado",
"supplier": null,
"created_at": "2020-04-23 09:35:00",
"updated_at": "2020-04-23 09:35:00",
"deleted_at": null,
"picture": [],
"pivot": {
"product_id": 8,
"product_tag_id": 1
},
"media": []
},
{
"id": 2,
"name": "cushew",
"supplier": "Fruit Salads",
"created_at": "2020-04-27 13:03:35",
"updated_at": "2020-04-27 13:03:35",
"deleted_at": null,
"picture": [],
"pivot": {
"product_id": 8,
"product_tag_id": 2
},
"media": []
}
],
"media": [
{
"id": 19,
"model_type": "App\\Product",
"model_id": 8,
"collection_name": "photo",
"name": "5eaedd370c100_jamies-iced-green-tea",
"file_name": "5eaedd370c100_jamies-iced-green-tea.jpg",
"mime_type": "image/jpeg",
"disk": "public",
"size": 36610,
"manipulations": [],
"custom_properties": {
"generated_conversions": {
"thumb": true
}
},
"responsive_images": [],
"order_column": 19,
"created_at": "2020-05-03 15:03:24",
"updated_at": "2020-05-03 15:03:24",
"url": "http://192.168.0.112/kwenu/storage/app/public/19/5eaedd370c100_jamies-iced-green-tea.jpg",
"thumbnail": "http://192.168.0.112/kwenu/storage/app/public/19/conversions/5eaedd370c100_jamies-iced-green-tea-thumb.jpg"
}
]
},
{
"id": 7,
"name": "Fruity",
"quantity": 1,
"type": "own",
"description": null,
"price": "18000.00",
"ingredients": null,
"deliveryfee": "0.00",
"supplier": null,
"duration": "1",
"category_id": 2,
"created_at": "2020-05-03 11:06:52",
"updated_at": "2020-05-03 11:06:52",
"deleted_at": null,
"photo": {
"id": 18,
"model_type": "App\\Product",
"model_id": 7,
"collection_name": "photo",
"name": "5eaea5c67a659_grilledchicken",
"file_name": "5eaea5c67a659_grilledchicken.jpg",
"mime_type": "image/jpeg",
"disk": "public",
"size": 13069,
"manipulations": [],
"custom_properties": {
"generated_conversions": {
"thumb": true
}
},
"responsive_images": [],
"order_column": 18,
"created_at": "2020-05-03 11:06:53",
"updated_at": "2020-05-03 11:06:56",
"url": "http://192.168.0.112/kwenu/storage/app/public/18/5eaea5c67a659_grilledchicken.jpg",
"thumbnail": "http://192.168.0.112/kwenu/storage/app/public/18/conversions/5eaea5c67a659_grilledchicken-thumb.jpg"
},
"sliderimages": [],
"tags": [
{
"id": 1,
"name": "Avocado",
"supplier": null,
"created_at": "2020-04-23 09:35:00",
"updated_at": "2020-04-23 09:35:00",
"deleted_at": null,
"picture": [],
"pivot": {
"product_id": 7,
"product_tag_id": 1
},
"media": []
},
{
"id": 2,
"name": "cushew",
"supplier": "Fruit Salads",
"created_at": "2020-04-27 13:03:35",
"updated_at": "2020-04-27 13:03:35",
"deleted_at": null,
"picture": [],
"pivot": {
"product_id": 7,
"product_tag_id": 2
},
"media": []
}
],
"media": [
{
"id": 18,
"model_type": "App\\Product",
"model_id": 7,
"collection_name": "photo",
"name": "5eaea5c67a659_grilledchicken",
"file_name": "5eaea5c67a659_grilledchicken.jpg",
"mime_type": "image/jpeg",
"disk": "public",
"size": 13069,
"manipulations": [],
"custom_properties": {
"generated_conversions": {
"thumb": true
}
},
"responsive_images": [],
"order_column": 18,
"created_at": "2020-05-03 11:06:53",
"updated_at": "2020-05-03 11:06:56",
"url": "http://192.168.0.112/kwenu/storage/app/public/18/5eaea5c67a659_grilledchicken.jpg",
"thumbnail": "http://192.168.0.112/kwenu/storage/app/public/18/conversions/5eaea5c67a659_grilledchicken-thumb.jpg"
}
]
}
]
}
THE PROBLEM IS INSTEAD OF STATE RETURNING cart AS AN ARRAY OF OBJECTS, IT RETURNS AN OBJECT OF OBJECTS, THANK YOU IN ADVANCE
i see addToCart action take the payload as an object { item }
and you try to access in reducer by action.payload without item
so
you can change
case ADD_TO_CART:
return{...state, cart:[...state.cart, action.payload.item]}
Or just update add to cart to be like so && all actions should be same
export const addToCart = (payload) => {
return (dispatch) =>{
dispatch({
type:ADD_TO_CART,
payload
}
}
Fixed it by changing the name of the cart array in the reducer from
const INITIAL_STATE = {
products:'',
cart:[],
category:'',
isVisible:false,
address:'',
selectedItem:[]
}
to:
const INITIAL_STATE = {
products:'',
carts:[],
category:'',
isVisible:false,
address:'',
selectedItem:[]
}
and the creating a class function for rendering the items in the cart component which i supplied to the renderitem function in the flatlist now the cart returns an array of objects. THANK YOU MUSTAFA FOR YOUR CONCERN
i am trying to solve this problem is, whenever user will click on category title then user will redirect to another page and will see the product_set data as per category id or slug.
i am probably new to ReactJs, it would be great if anybody could help me out what i am trying to solve is. thank you so much in advance.
end point url: "http://localhost:8000/api/p_category"
Api data:
[
{
"id": 1,
"title": "category01",
"slug": "category01",
"description": "",
"image": "http://localhost:8000/media/cat2_KpMV1YQ.jpg",
"product_set": [
{
"url": "http://localhost:8000/api/p/product01",
"id": 1,
"title": "product01",
"slug": "product01",
"image": "http://localhost:8000/media/product2_EMWEgQI.png",
"price": 5,
"status": true,
"created_on": "2020-04-19T18:44:03Z"
},
]
},
{
"id": 3,
"title": "category03",
"slug": "category03",
"description": "category03 desc..",
"image": "http://localhost:8000/media/cat3_9dal1uP.jpg",
"product_set": [
{
"url": "http://localhost:8000/api/p/product03",
"id": 3,
"title": "product03",
"slug": "product03",
"image": "http://localhost:8000/media/product5.png",
"price": 3,
"status": true,
"created_on": "2020-04-19T18:44:03Z"
},
{
"url": "http://localhost:8000/api/p/product06",
"id": 5,
"title": "product06",
"slug": "product06",
"image": "http://localhost:8000/media/product6_rkmAlce.png",
"price": 12,
"status": true,
"created_on": "2020-04-19T18:44:03Z"
}
]
}
]
You can do like this,
import { React } from "react";
class categoryListExample extends React.Component{
state={
categoryList:[],
category:''
}
async componentDidMount(){
let res=await fetch("http://localhost:8000/api/p_category")
//assuming you are getting data in response.data
this.setState({categoryList:res.data})
}
categoryChangeHandler=(category)=>{
this.setState({category})
}
render(){
const {categoryList,category}=this.state
if (categoryList.length>0) {
return(
<div>
<ul>
{categoryList.map(category=><li key={category.id} onClick={this.categoryChangeHandler}>{category.title}</li>)}
</ul>
<CategoryComponent category={category.product_set}/>
</div>
)
} else {
return(
<div>
Loading...
</div>
)
}
}
}
export default categoryListExample;
Noob to react and everything that has to do with web-developing pretty much. I'm trying to create a list in a Navbar with buttons that redirects the user to a new page. I'm fetching sports from a JSON-file and I have the code below to reduce/get rid of all the duplicates. My question now is what the best practice to create a list in, e.g. a navbar with a button that gets one sport each. I have a total of 5 sports in {postList} and I have no Idea how to split them up from the SportList.js-file. My goal is attaching them to an icon somehow (like a football for football), that sends the user to the football-page (where you can see all the football games). Not really sure where to start.
I hope my question is not to confusing, english is not my first language. Any help and/or hints is awesome. Ask me if it doesn't make sense and I will try to rephrase the question. Thank you!
import React, { Component } from 'react'
import axios from 'axios'
class SportList extends Component {
state = {
posts: []
}
componentDidMount(){
axios.get('https://data.json')
.then(res => {
this.setState({
posts: res.data
});
})
}
render() {
const { posts } = this.state;
const uniquePosts = Object.values(posts.reduce((r,c) => {
r[c.sport] = c
return r
}, {}))
const postList = uniquePosts.length ? (
uniquePosts.map(post => {
return (
<div key={post.id}>
<div>
{post.sport}
</div>
</div>
)
})
) : (<div>No Sports Available</div>)
return (<div>{postList}</div>);
}
}
export default SportList
You need to install two packages react-router-dom and lodash.
After the api call , once you get the data. Get the sport names, create each components for the sport. Pass the data to each component.
Note: Since i don't have the api, i have used to get it from a file, so you can call the api in the componentDidMount and set the data to state.
Also use the Route component inorder to render the data based on each component load.
I hope this will solve the issue. Please let me know if any issue occurred.
// App.js
import React, { Component } from 'react';
import './App.css';
import Aux from './Aux';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Data from './Data';
import FootBall from './FootBall';
import EachNavLink from './EachNavLink';
import {groupBy} from 'lodash'
class App extends Component {
state = {
apiData: Data
}
getData = (sport) => {
let data = groupBy(this.state.apiData, "sport")
return data[sport];
}
renderTabs = () => {
const { apiData } = this.state
const sports = Array.from(new Set(apiData.map(o => o.sport)))
const tabs = sports.map((item, index) => {
return (
<EachNavLink
key={index}
href={`/${item}`}
name={item}
/>
)
})
return tabs
}
render() {
const { apiData } = this.state
return (
<BrowserRouter>
<Aux>
<Aux>
{
apiData.length > 0 ?
this.renderTabs()
:
<p>Data is Loading... Please wait.</p>
}
</Aux>
<div className="content">
<Switch>
<Route path="/FOOTBALL" render={(routeProps) => (<FootBall {...routeProps} data={apiData.length > 0 ? this.getData("FOOTBALL") : []} />)} />
</Switch>
</div>
</Aux>
</BrowserRouter>
);
}
}
export default App;
// Data.js
const data = [
{
"awayName": "Panthrakikos Komotini",
"createdAt": "2015-12-18T12:30:39.228Z",
"group": "Greek Cup",
"homeName": "Chania FC",
"id": 1002916450,
"name": "Chania FC - Panthrakikos Komotini",
"objectId": "1UaQjc7lIb",
"sport": "FOOTBALL",
"country": "ENGLAND",
"state": "STARTED"
},
{
"awayName": "PAOK Thessaloniki",
"createdAt": "2015-12-18T12:30:39.234Z",
"group": "Greek Cup",
"homeName": "Olympiakos Volos",
"id": 1002916451,
"name": "Olympiakos Volos - PAOK Thessaloniki",
"objectId": "UPJ240T2Qj",
"sport": "FOOTBALL",
"country": "FRANCE",
"state": "STARTED"
},
{
"awayName": "Ukraine U18",
"createdAt": "2015-12-18T12:30:39.244Z",
"group": "Under 18",
"homeName": "Israel U18",
"id": 1003022920,
"name": "Israel U18 - Ukraine U18",
"objectId": "fZZUhitsVt",
"sport": "FOOTBALL",
"country": "SWEDEN",
"state": "STARTED"
},
{
"awayName": "Stade Gabesien",
"createdAt": "2015-12-18T12:30:39.249Z",
"group": "Ligue 1",
"homeName": "CA Bizertin",
"id": 1003015194,
"name": "CA Bizertin - Stade Gabesien",
"objectId": "Bf52z7GIut",
"sport": "FOOTBALL",
"country": "SWEDEN",
"state": "STARTED"
},
{
"awayName": "AS de la Marsa",
"createdAt": "2015-12-18T12:30:39.255Z",
"group": "Ligue 1",
"homeName": "Club Africain",
"id": 1003015197,
"name": "Club Africain - AS de la Marsa",
"objectId": "sFjPkmljKv",
"sport": "FOOTBALL",
"country": "ENGLAND",
"state": "STARTED"
},
{
"awayName": "Kastamonuspor",
"createdAt": "2015-12-18T12:30:39.261Z",
"group": "T\u00fcrkyie Kupasi",
"homeName": "Kar\u015f\u0131yaka",
"id": 1003016331,
"name": "Kar\u015f\u0131yaka - Kastamonuspor",
"objectId": "cRqV2RTmsu",
"sport": "FOOTBALL",
"country": "FRANCE",
"state": "FINISHED"
},
{
"awayName": "Allen, Gareth",
"createdAt": "2015-12-18T12:30:39.266Z",
"group": "German Masters Qualifiers",
"homeName": "Ding Junhui",
"id": 1003018193,
"name": "Ding Junhui - Allen, Gareth",
"objectId": "nPuz011p0W",
"sport": "SNOOKER",
"country": "SWEDEN",
"state": "NOT_STARTED"
},
{
"awayName": "Lines, Peter",
"createdAt": "2015-12-18T12:30:39.272Z",
"group": "German Masters Qualifiers",
"homeName": "Trump, Judd",
"id": 1003018186,
"name": "Trump, Judd - Lines, Peter",
"objectId": "CSJn3kZhdx",
"sport": "SNOOKER",
"country": "ENGLAND",
"state": "NOT_STARTED"
},
{
"awayName": "SKIF-Krasnodar",
"createdAt": "2015-12-18T12:30:39.278Z",
"group": "Cup",
"homeName": "Dinamo Astrakhan",
"id": 1003027200,
"name": "Dinamo Astrakhan - SKIF-Krasnodar",
"objectId": "enCbqOuRLr",
"sport": "HANDBALL",
"country": "SWEDEN",
"state": "STARTED"
},
{
"awayName": "THK Tver",
"createdAt": "2015-12-18T12:30:39.283Z",
"group": "VHL",
"homeName": "Zauralie Kurgan",
"id": 1002988754,
"name": "Zauralie Kurgan - THK Tver",
"objectId": "7HWfuCIMlp",
"sport": "ICE_HOCKEY",
"country": "ENGLAND",
"state": "STARTED"
},
{
"awayName": "Doumbia, SReboul, F",
"createdAt": "2015-12-18T12:30:39.289Z",
"group": "Nigeria",
"homeName": "Harris, L G MMaamoun, K M",
"id": 1003026313,
"name": "Harris, L G MMaamoun, K M - Doumbia, SReboul, F",
"objectId": "JxrZyQKTrw",
"sport": "TENNIS",
"country": "FRANCE",
"state": "STARTED"
},
{
"awayName": "Halebian, Alexios",
"createdAt": "2015-12-18T12:30:39.294Z",
"group": "Dominican Republic",
"homeName": "Bangoura, Sekou",
"id": 1003026667,
"name": "Bangoura, Sekou - Halebian, Alexios",
"objectId": "tALMRNqAxD",
"sport": "TENNIS",
"country": "SWEDEN",
"state": "NOT_STARTED"
},
{
"awayName": "Roberts, Justin",
"createdAt": "2015-12-18T12:30:39.300Z",
"group": "Dominican Republic",
"homeName": "Pla Malfeito, Jaume",
"id": 1003026666,
"name": "Pla Malfeito, Jaume - Roberts, Justin",
"objectId": "KGA9nqYAJl",
"sport": "TENNIS",
"country": "ENGLAND",
"state": "FINISHED"
},
{
"awayName": "Mridha, J",
"createdAt": "2015-12-18T12:30:39.306Z",
"group": "Qatar",
"homeName": "Clayton, Scott",
"id": 1003026476,
"name": "Clayton, Scott - Mridha, J",
"objectId": "utc63de1Fl",
"sport": "TENNIS",
"country": "FRANCE",
"state": "STARTED"
},
{
"awayName": "Kania, PKerkhove, L",
"createdAt": "2015-12-18T12:30:39.311Z",
"group": "Ankara",
"homeName": "Buyukakcay, CKrunic, A",
"id": 1003026234,
"name": "Buyukakcay, CKrunic, A - Kania, PKerkhove, L",
"objectId": "mTVUIuYdbF",
"sport": "TENNIS",
"country": "SWEDEN",
"state": "NOT_STARTED"
},
{
"awayName": "Chernetsova, DPerper, A",
"createdAt": "2015-12-18T12:30:39.317Z",
"group": "El Kantaoui",
"homeName": "Baskova, DPodlinska, M",
"id": 1003026673,
"name": "Baskova, DPodlinska, M - Chernetsova, DPerper, A",
"objectId": "heL53W56d2",
"sport": "TENNIS",
"country": "FRANCE",
"state": "STARTED"
},
{
"awayName": "Njoze, M",
"createdAt": "2015-12-18T12:30:39.322Z",
"group": "El Kantaoui",
"homeName": "Stoilkovska, M",
"id": 1003026214,
"name": "Stoilkovska, M - Njoze, M",
"objectId": "gldlV9xhi2",
"sport": "TENNIS",
"country": "SWEDEN",
"state": "STARTED"
},
{
"awayName": "Haas, Barbara",
"createdAt": "2015-12-18T12:30:39.328Z",
"group": "Navi Mumbai",
"homeName": "Jia-Jing Lu",
"id": 1003026299,
"name": "Jia-Jing Lu - Haas, Barbara",
"objectId": "V6Qsm2Wlms",
"sport": "TENNIS",
"country": "ENGLAND",
"state": "FINISHED"
}
]
export default data
// Aux.js
const aux = ({children}) => children
export default aux
// EachNavLink.js
import React from 'react';
import {NavLink} from 'react-router-dom';
const eachNavLink = ({href,name}) => {
return(
<div>
<NavLink
to={href}
activeClassName="active"
>
{name}
</NavLink>
</div>
)
}
export default eachNavLink
// FootBall.js
import React from 'react';
const football = (props) => {
const { data } = props
return (
data.map((item, index) => {
return (
<div key={index}>
<ul>
<li>Away Name: {item.awayName}</li>
<li>Country: {item.country}</li>
<li>Group: {item.group}</li>
</ul>
</div>
)
})
)
}
export default football