What I Want to Do:
I want to render a list of elements using .map, then sort by most recent on top. I've tried adding .sort and .filter before rendering the element, but it doesn't seem to be working. I've done some quick Google searches, but came across posts which don't seem relevant to what i'm trying to do. (or it's just me).
I want to sort by date, with the most recent on top.
Render Component:
import React from "react";
import TransactionEntry from "./TransactionEntry";
function Transactions({ transactionList }) {
return (
<div className="flex flex-col items-start justify-start w-full h-[520px] overflow-auto gap-3 no-scrollbar">
{transactionList.map((transaction) => {
return (
<TransactionEntry
id={transaction.id}
retailer={transaction.retailer}
category={transaction.category}
price={transaction.price}
dateAdded={transaction.dateAdded}
/>
);
})}
</div>
);
}
export default Transactions;
Data Structure:
[
{
"id": "ts001",
"category": "Category",
"retailer": "Retailer",
"price": 1.99,
"dateAdded": "04/02/01"
},
{
"id": "ts002",
"category": "Category",
"retailer": "Retailer",
"price": 13.99,
"dateAdded": "04/02/04"
},
{
"id": "ts003",
"category": "Category",
"retailer": "Retailer",
"price": 119.99,
"dateAdded": "04/02/09"
}
]
You can sort before mapping in this way
{transactionList.sort((a, b) => new Date(a.dateAdded) - new Date(b.dateAdded)).map((transaction) => {
return (
<TransactionEntry
id={transaction.id}
retailer={transaction.retailer}
category={transaction.category}
price={transaction.price}
dateAdded={transaction.dateAdded}
/>
);
})}
Related
I'm trying to build the footer of Netflix dynamically with Reactjs and styled components but i couldn't figure it out how to do it. Any help would be apprciated :)
I created the links in a links.json file
[
{
"id": 1,
"link": "FAQ"
},
{
"id": 2,
"link": "Investor Relations"
},
{
"id": 3,
"link": "Privacy"
},
{
"id": 4,
"link": "Speed Test"
},
{
"id": 5,
"link": "Help Center"
},
{
"id": 6,
"link": "Jobs"
},
{
"id": 7,
"link": "Cookie Preferences"
},
{
"id": 8,
"link": "Legal Notices"
},
{
"id": 9,
"link": "Account"
},
{
"id": 10,
"link": "Ways to Watch"
},
{
"id": 11,
"link": "Coorporate Information"
},
{
"id": 12,
"link": "Only on Netflix"
},
{
"id": 13,
"link": "Media Center"
},
{
"id": 14,
"link": "Terms of use"
},
{
"id": 15,
"link": "Contact US"
}
]
Then in my footer component I tried to perform the filter and map functions but i can't implement the code: it only display 4 items per column inside a ul tag :(((
import React from 'react'
import linksData from '../fixtures/links'
import './Footer.css'
function Footer() {
return (
// <div>
// {linksData
// .filter()
// .map((item, index)=>(
// <li key={index}>{item.link}</li>
// )
// )}
// </div>
<div className="site-footer-wrapper">
<div className="site-footer">
<p className="footer-top">
<a className='footer-top-a' href> Questions? Contact US</a>
</p>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
<ul className='footer-links'>
<li className='footer-link-item'>FAQ</li>
<li className='footer-link-item'>Investor Relations</li>
<li className='footer-link-item'>Privacy</li>
<li className='footer-link-item'>Speed Test</li>
</ul>
</div>
</div>
)
}
export default Footer
I would appreciate any help of how to do this, either with the map() function or with CSS rules.
Thank you
One thing that could be beneficial is separating the concerns. Create a separate component that will handle one column at a time.
In my case, I created a Column component that returns a 'ul' JSX tag and display 'li' JSX tags based on linksToDisplay array received as props.
const Column = ({ linksToDisplay, key }) => (
<ul key={key} className='px-4'>
{linksToDisplay.map((item) => (
<li key={item.id}>{item.link}</li>
))}
</ul>
);
Then, I use my Column component inside my Footer component to display the columns based on a set criteria.
const Footer = () => {
return (
<div className='container mx-auto flex px-2 lg:px-5 py-24 h-screen
items-center justify-center flex-row'>
{links.map((link, index) => {
// So you get a new column after 4 items have been displayed
if (index % 4 === 0) {
// Array.slice to get the next 4 links in the array
const nextFourLinks = links.slice(index, index + 4);
return <Column key={link.id} linksToDisplay={nextFourLinks}
/>;
}
})}
</div>
);
};
After that, apply some styling to your elements and in my case I am using tailwindCSS and you should have your columns displaying the links.
Output:
For reference:
Array.prototype.slice()
There is a page where you can see the details of a user's loan. There is a decorator where I return values using the get () method. In general, there is a partial refund, which returns items of partial payments as shown in the photo. My problem is that I cannot specify all partial payments, only receive one by one.
Loan Details component:
<div className="ClientLoanDetails__card__content__inner__wrapper">
{Object.keys(payments[0]).map(val => {
{
[payments[0][val]].map((payment: any, index: number) => (
<div className="ClientLoanDetails__card__content-inner" key={index}>
{paymentsFields.map((item, indexInner) => (
<div className="ClientLoanDetails__card__content-item" key={indexInner}>
<div className="ClientLoanDetails__card__content-item__title">
{item.title}
</div>
<div className="ClientLoanDetails__card__content-item__value">
{payment[item.key]}
</div>
</div>
))}
</div>
));
}}
)
}}
</div>
This is code snippet for key & titles from loan.ts:
export const repaymentsFields = [
{
key: 'issuedDate',
title: lang.CLIENTS.REPAYMENTS.ISSUED_DATE,
},
{
key: 'period',
title: lang.CLIENTS.REPAYMENTS.PERIOD_IN_DAYS,
},
]
JSON of repayments:
"partialRepayments": [
{
"orderId": "A11Fz090VT1BmObJ0S-0",
"repaidPrincipalAmount": {
"amount": 250000.0
},
"repaidInterestAmount": {
"amount": 0
},
"repaidOverdueAmount": {
"amount": 0
},
"repaidProlongationAmount": {
"amount": 0
},
"started": "2020-11-09T16:52:08.981+0600",
"completed": "2020-11-09T16:52:21.170+0600",
"period": 25,
"timestamp": "2020-11-09T16:52:21.174+0600"
},
{
"orderId": "A11Fz090VT1BmObJ0S-1",
"repaidPrincipalAmount": {
"amount": 300000.0
},
"repaidInterestAmount": {
"amount": 0
},
"repaidOverdueAmount": {
"amount": 0
},
"repaidProlongationAmount": {
"amount": 0
},
"started": "2020-11-09T16:54:31.923+0600",
"completed": "2020-11-09T16:54:46.313+0600",
"period": 25,
"timestamp": "2020-11-09T16:54:46.317+0600"
}
],
the problem is that it is impossible to display the values that come as in the photo (one loan may have several repayments)
I have to return all values from an Object
IMAGE of console
Why don't you loop through the partialPayementResponse and access each field through the dot . notation ? Such as follows:
<div>
{partialRepayments.map((item, index) => {
return (
<div key={index}>
<div>Completed: <span>{item.completed}</span></div>
<div>orderId: <span>{item.orderId}</span></div>
<div>period: <span>{item.orderId}</span></div>
<div>repaidInterestAmount: <span>{item.repaidInterestAmount.amount}</span></div>
<div>repaidOverdueAmount: <span>{item.repaidOverdueAmount.amount}</span></div>
<div>repaidPrincipalAmount: <span>{item.repaidPrincipalAmount.amount}</span></div>
<div>repaidProlongationAmount: <span>{item.repaidProlongationAmount.amount}</span></div>
<div>started: <span>{item.started}</span></div>
<div>timestamp: <span>{item.timestamp}</span></div>
</div>)
})}
</div>
I wrote it without using your classNames but I think you get the idea
Not sure what's the problem here.
Can't u just iterate over these things?
Or create function and then display the thing that function returns...
for example:
displayAppropriateFields = () => {
let returnedArray = [];
returnedArray.push(<div> Some text in the div </div>);
for(let i=0; i<someArray.length; i++) {
returnedArray.push(<span> someArray[i] </span>)
}
return returnedArray;
}
And then display it in render method like so:
this.displayAppropriateFields();
I am trying to manipulate a table data on the basis of the search in the table. So, what I have is this type of data:
this.props.datalist = {
"content": [{
"id": "5b7d4a566c5fd00507501051",
"companyId": null,
"title": "Senior/ Lead UI Developer",
"jobDescription": null,
"technology": "java"
},{
"id": "5b7d4a566c5fd005075011",
"companyId": null,
"title": "ead UI Developer",
"jobDescription": null,
"technology": "angular"
}]
}
In this I have this data coming from my `redux state. So I show this to user in the table form by passing this as a props.
I have a search field:
<input type="text"
id="searchJob"
className="form-control-sm border-0 flex-grow-1"
value={this.state.search}
placeholder="Company Name / Technology / Job title"
onChange={this.onInputChnage}
/>
<i className="fa fa-search search-job"></i>
onInputChnage = (e) => {
this.setState({
search: e.target.value
})
}
<div className="col-12 pr-0 pl-0">
<UserJobsTabel jobList={filteredList} />
</div>
</div>
Here , I got the filtered data in this array using filter
[{
"id": "5b7d4a566c5fd00507501051",
"companyId": null,
"title": "Senior/ Lead UI Developer",
"jobDescription": null,
"technology": "java"
},{
"id": "5b7d4a566c5fd005075011",
"companyId": null,
"title": "ead UI Developer",
"jobDescription": null,
"technology": "angular"
}]
Now, while setting state,
I am doing like this.
this.setState({ search: data })
If I want to set the state as with key like "content": [{}] like this then How can I do this ?
Because the way I am using it is like,
{this.props.dataList && this.props.dataList.content && this.props.dataList.content.length > 0 && this.props.dataList.content.sort((a, b) => b.createdAt - a.createdAt).map((item, key) => {
What I want to do is that the table data has two keys. One is title and Technolgoy now, search happens then it should check in the object and return the matched objects and that will be displayed on table.
Now if search has again nothing then it should show the default data that was present. Is there any way to do this?
The simplest way would be to create a variable in the render method containing the filtered props.datalist and use that for displaying.
something like
render(){
const { datalist:{content} } = this.props;
const { search } = this.state;
const filteredList = content.filter(job=>Object.values(job).some(value=>value.includes(search)));
return (<div>
//whatever
{filteredList.map(job=>....)}
</div>)
}
You could also do the filtering in the onInputChnage and store the filtered list in the local state.
Currently I am struggling with iterating over an object containing an array with objects. (and nested ones) I am trying to create a generic Table Component in React so it can be used by many views.
What did I setup?
tableData.map((prop, key) => {
return (
<TableRow key={key}>
<TableCell className={classes.tableCell} key={key}>
{prop.number}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.TableType.max_occupancy}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.price}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.TableType.description}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
<Button fullWidth color="primary">
Remove
</Button>
</TableCell>
</TableRow>
);
})
The problem that I am facing right now?
I can not create the content above in a dynamic way. I am encountering several issues like for example:
The nested objects logic
The logic should not clash with other implementations in other pages. (react)
What would I like to achieve?
I would like to achieve something that is generic and can be used in a wide range of scenarios and does not clash with other pages where this component is being used.
In the end it should look something like this in a visual way:
What data do I have?
[
{
"id": 1,
"number": 1,
"status": true,
"price": 12,
"table_type_id": 1,
"venue_id": 1,
"TableType": {
"id": 1,
"description": "Small Table",
"max_occupancy": 3
}
},
{
"id": 2,
"number": 2,
"status": true,
"price": 2,
"table_type_id": 2,
"venue_id": 1,
"TableType": {
"id": 2,
"description": "Medium Table",
"max_occupancy": 6
}
}
]
The Codesandbox directory with the full project:
https://codesandbox.io/embed/lwzz4j9mz?autoresize=1&eslint=1
The fill we are talking about is located at the Components/Table/Table.jsx. (I have added some dummy data in the comments that needs to be parsed to Table rows and cells)
Properties that needs be used in the view:
number
price
id
TableType
Hopefully someone can come up with a smart idea to help me out with this issue! Cheers for all the help and hopefully we can fix this together.
You should probably use an external library to get this done. But if you want to go for an in house approach this would be one way to go about it.
To the component, send the data and the header.The header should also specify how the data should be parsed to receive it's value.
var defaultTemaplate = '<TableRow><TableCell style={{ textAlign: "center" }}>Woooops! You haven\'t applied any tables for this venue yet. To start renting out tables you should add at least 3 tables tothe app. Just press the button above to start imediately.</TableCell></TableRow>'
var tableHead = [{
title: 'number',
type: 'data',
path: 'number'
},
{
title: 'TableType',
type: 'data',
path: 'TableType.description'
},
{
title: 'Edit/delete',
type: 'template',
templateString: '<button></button>'
}
] //for all columns
var tableData = [{
"id": 1,
"number": 1,
"status": true,
"price": 12,
"table_type_id": 1,
"venue_id": 1,
"TableType": {
"id": 1,
"description": "Small Table",
"max_occupancy": 3
}
},
{
"id": 2,
"number": 2,
"status": true,
"price": 2,
"table_type_id": 2,
"venue_id": 1,
"TableType": {
"id": 2,
"description": "Medium Table",
"max_occupancy": 6
}
}
]
console.log(genRows(tableData))
function getTableCells(data) {
return tableHead.map((opts) => {
if (opts.type === 'data') {
return `<TableCell className={classes.tableCell}>${_.at(data, opts.path)}</TableCell>`
}
if (opts.type === 'template') {
return opts.templateString
}
})
}
function genRows(tableData) {
if (tableData.length < 0) return defaultTemaplate;
return tableData.map((rowData) => `<TableRow>${getTableCells(rowData)}</TableRow>`)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
This is just an example to demonstrate one approach you could take, not full fledged code and can defenetly be improved.
I've been trying to learn React Native but it has been tougher than I thought. I can't create a simple "master-detail" app (and I couldn't find a good, simple tutorial explaining how to do it either).
I've managed to display a list of categories. After clicking one, it should display the category name + the list of items from this:
const data = [{
"category": "Fruits",
"items": [{
"name": "Apple",
"icon": "apple.png"
}, {
"name": "Orange",
"icon": "orange.png"
}]
}, {
"category": "Vegetables",
"items": [{
"name": "Lettuce",
"icon": "lettuce.png"
}, {
"name": "Mustard",
"icon": "mustard.png"
}]
}];
On my main class, I managed to display a list of categories:
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) =>
<Text onPress={this.onPressItem.bind(this, rowData.category)}>
{rowData.category}
</Text>}
/>
In my onPressItem I have the following:
onPressItem(category) {
this.props.navigator.push({
name: 'DetailView',
component: DetailView,
passProps: {
category
}
});
}
In my detail view, the category name is not being displayed:
class DetailView extends Component {
render() {
return (
<View style={ styles.container }>
<Text>Category: { this.props.category }</Text>
<TouchableHighlight onPress={ () => this.props.navigator.pop() }>
<Text>GO Back</Text>
</TouchableHighlight>
</View>
);
}
}
I'd really appreciate if someone can help me with this. It's probably something silly I'm doing wrong. Creating this simple thing can't be that hard. :/
Full code
I found a solution. I was making a mistake when rendering the view:
return React.createElement(
route.component,
{ navigator },
{...route.passProps}
);
The right way is:
return React.createElement(
route.component,
{ navigator, ...route.passProps }
);
Thanks to mehcode for helping me out.