Remove repeated elements - javascript

I'm displaying US region incidents from Google Cloud API, but the problem is that it displays also repeated data, example:enter image description here
How can I remove the repeated ones? Here's the code.
DATA RETRIEVING:
export const getGoogleStatus = async () => {
const response = await axios.get('https://status.cloud.google.com/incidents.json')
console.log('Raw Data: ', response.data)
const status = response.data.map((e) => {
return {
name: e.affected_products.map((e) => {
return e.title
}),
status: e.most_recent_update.status,
location: e.most_recent_update.affected_locations.map((e) => {
return e.title
}).filter((r) => r.includes("(us-"))
}
})
return status
}
DATA DISPLAYING IN FRONTEND:
export default function GoogleStatusSummary({ listStatus }) {
if (!listStatus) return <div>Loading...</div>
return (
<Grid container padding={2} justifyContent='center'>
<Grid item padding={2}>
<Typography variant='h1' marginLeft={5}>
<TwitterIcon sx={{ mr: 2, mt: 1 }} />
Google API Status
</Typography>
{listStatus.map((item, index) => {
const { name, status, location } = item
const colorStatus = status === 'AVAILABLE' ? 'success' : 'danger'
return (
location.length > 0 && (
<Grid display='flex' m={3} key={index}>
<RadioButtonCheckedIcon sx={{ ml: 2, mt: 1 }} color={colorStatus} />
<Grid ml={2}>
<Typography variant='h4'>
{name}
</Typography>
<Typography variant='h6' style={{ fontSize: 12 }}>
{status.charAt(0).toUpperCase() + status.slice(1)}
</Typography>
</Grid>
</Grid>
)
)
})
}
</Grid>
</Grid>
)

Related

How to send/receive props to BasicLayout (#devexpress/dx-react-scheduler)

I'm from Angular and new to React. Im doing well but here is a problem I'm stuck at. As you can see I have BasicLayout and AppointmentForm, both are in one file. BasicLayout is being used inside AppointmentForm but not like an element i.e <BasicLayout/> so I'm not able to understand how to pass props or its even possible now. I want to trigger commitChanges(inside AppointmentForm) function when onSubmit(inside Basic Layout) function is triggered. How can I pass props between these components?
const BasicLayout = (props) => {
const formik = useFormik({
initialValues: {
title: '',
agenda: '',
description: '',
participants: [],
host: user?.id,
guest: '',
location: '',
},
validationSchema,
onSubmit: async (values) => {
values.startDate = props.appointmentData.startDate;
values.endDate = props.appointmentData.endDate;
values.guest = values.guest?._id;
createAppointment(values);
console.log(values);
},
});
return (
<Container>
<Typography sx={{ fontSize: 24, fontWeight: 'bold' }} color="text.primary" gutterBottom>
Create Appointment
</Typography>
<Box sx={{ flexGrow: 1 }}>
<FormikProvider value={formik}>
<Form autoComplete="off" onSubmit={handleSubmit}>
<Grid container spacing={2}>
<Grid item xs={6} md={6}>
<TextField
label="Title"
color="secondary"
id="title"
type="text"
key="title"
value={formik.values.title}
onChange={formik.handleChange}
{...getFieldProps('title')}
error={Boolean(touched.title && errors.title)}
helperText={touched.title && errors.title}
fullWidth
/>
</Grid>
<Grid item container xs={12} md={12} direction="row" justifyContent="center" alignItems="center">
<LoadingButton size="medium" type="submit" variant="contained" loading={isSubmitting}>
Create
</LoadingButton>
</Grid>
</Grid>
</Form>
</FormikProvider>
</Box>
<ToastContainer />
</Container>
);
};
const AppointmentsDashboard = (props) => {
const commitChanges = ({ added, changed, deleted }) => {
console.log(props);
console.log({ added, changed, deleted });
if (added) {
if (!isValidate) {
notify('Please fill all required fields', 'error');
return;
}
const startingAddedId = data.length > 0 ? data[data.length - 1].id + 1 : 0;
setData([...data, { id: startingAddedId, ...added }]);
}
if (changed) {
setData(
data.map((appointment) =>
changed[appointment.id] ? { ...appointment, ...changed[appointment.id] } : appointment
)
);
}
if (deleted !== undefined) {
setData(data.filter((appointment) => appointment.id !== deleted));
}
return data;
};
return (
<>
<Paper>
<Scheduler data={data} height={660}>
<ViewState currentDate={currentDate} />
<EditingState
onCommitChanges={commitChanges}
addedAppointment={addedAppointment}
onAddedAppointmentChange={changeAddedAppointment}
appointmentChanges={appointmentChanges}
onAppointmentChangesChange={changeAppointmentChanges}
editingAppointment={editingAppointment}
onEditingAppointmentChange={changeEditingAppointment}
onAppointmentFormClosing={() => {
console.log('asdasd');
}}
allowAdding={true}
/>
<WeekView startDayHour={9} endDayHour={17} />
<AllDayPanel />
<EditRecurrenceMenu />
<ConfirmationDialog />
<Appointments />
<AppointmentTooltip showOpenButton showDeleteButton />
<AppointmentForm basicLayoutComponent={BasicLayout} />
</Scheduler>
</Paper>
</>
);
};
export default AppointmentsDashboard;

Is rendering the Autocomplete options list with column headers possible?

I would like to know if it is possible to customise the above example so that the list would have column headers such as Title and duration. I have tried to see if I could get it to work using a custom ListBox, but no such luck. Below is a snippet of my own code:
const PopperMy = function (props: PopperProps) {
return <Popper {...props} style={{ width: 500 }} placement='bottom-start' />;
};
return (
<Autocomplete
filterOptions={(x) => x}
getOptionLabel={(option: Record<string, unknown>) => `${option.order}, ${option.name}, ${option.email}, ${option.phone}, ${option.location}`}
renderOption={(props, option: any) => {
return (
<li {...props} key={option.ID} >
Order: {option.order}, Name: {option.name}, Email: {option.email}, Phone: {option.phone}, Location: {option.location}, Status: {option.status}
</li>
);
}}
options={results}
value={selectedValue}
clearOnBlur={false}
freeSolo
PopperComponent={PopperMy}
disableClearable={true}
includeInputInList
onChange={(ev, newValue) => {
setSelectedValue(newValue);
}}
onInputChange={(ev, newInputValue) => {
setInputValue(newInputValue);
}}
renderInput={(params) => (
<TextField {...params} />
)} /> )
this is achievable by customizing the popper component. In your case, something like `
const PopperMy = function (props) {
const { children, ...rest } = props;
return (
<Popper {...rest} placement="bottom-start">
<Box display="flex" justifyContent="space-between" px="16px">
<Typography variant="h6">Title</Typography>
<Typography variant="h6">Year</Typography>
........... rest of the titles
</Box>
{props.children}
</Popper>
);
};
`
would work. Here is a working example i have created - https://codesandbox.io/s/heuristic-golick-4sv24u?file=/src/App.js:252-614

react matrerial ui Error: Objects are not valid as a React child If you meant to render a collection of children, use an array instead

I am facing the error with the following code and there seems to be no fixes that is solving my issue.
componentDidMount() {
axios.get('http://localhost:8080/home')
.then((response) => {
this.setState({
data: response.data
});
})
.catch((err) => {
console.log(err);
});
}
response from server:
{"data":{"count":{"monthly_blog_count":1,"total_blog_count":1,"monthly_poem_count":0,"total_poem_count":0,"monthly_song_count":0,"total_song_count":0,"monthly_graphics_count":1,"total_graphics_count":1},"latest_graphics":{"link":"ganesha.svg"},"latest_blog":{"title":"test","created":"2021-05-08T07:49:50.000Z","name":"Abhishek Banerjee"},"latest_blog_list":[{"title":"test","created":"2021-05-08T07:49:50.000Z","name":"Abhishek Banerjee"}]}}
<Poems data={data} />
Here's the poem component edited as it's not allowing all code:
the base element is card. I took out code from the poem component since it's complaining not enough text. I have protypes validation on the component as well.
const Poems = (props) => {
const {
data: count,
'data.count.total_poem_count': totalPoemCount,
'data.count.monthly_poem_count': monthlyPoemCount,
} = props;
return (
<Card
sx={{ height: '100%' }}
{...props}
>
<Grid item>
<Typography
color="textPrimary"
variant="h3"
>
{ totalPoemCount }
</Typography>
</Grid>
<Typography
sx={{
color: green[900],
mr: 1
}}
variant="body2"
>
{ monthlyPoemCount }
</Typography>
</card>
);
};
Edit
putting { data?.data?.count?.total_poem_count } works like a charm. But the proptypes validation is gone. Can anyone suggest me how to get proptypes as well working.
Best Practice is to use axios package for fetching api.
axios.get("http://localhost:8080/home")
.then((response) => {
this.setState({
data: response.data
});
})
.catch((err) => {
console.log(err);
});
passing data to component
<Poems data={this.state.data} />
child component
const Poems = ({ data }) => {
const dataToRender = data?.data
return (
<Card
sx={{ height: '100%' }}
{...props}
>
<Grid item>
<Typography
color="textPrimary"
variant="h3"
>
{ dataToRender.count.totalPoemCount }
</Typography>
</Grid>
<Typography
sx={{
color: green[900],
mr: 1
}}
variant="body2"
>
{ dataToRender.count.monthlyPoemCount }
</Typography>
</card>
);
};
<

redux and react unwanted effect

Hello everyone 👋
I'm trying to make a cart functionality with redux.
2.Description of problem:
The problem is that as soon as I want to remove a product that is not the last from my basket.
Redux does delete the desired product from the store, but at the frontend I still see the product and react deletes the last product from the list (the one I didn't want to delete).
I have to go to another page without reloading and returning to the basket to see react to reset
If I remove the last product from the list the removal works as it should.
I have made a video link that are served by google drive:
https://drive.google.com/file/d/1miZA4B1Ay5OZZBGPj1bCcQHsGv21oVW_/view
Here is the redux effect I want or expected to have ( this is the action of removing the latest product from cart list :
If I have several products in my cart and I just want to delete a product without it being the last ( unwanted effect ):
The ADD_TO_CART_ACTION dispatch
store.dispatch({
type: ADD_PRODUCT_TO_CART_ACTION,
payload: {
data: {
productID: data.product.id,
attributeID: RadioState,
price: data.price,
quantity: 1
}
}
})
this is my cart reducer:
export function CartReducer(state = [], action){
const cart = [...state]
switch (action.type){
case 'ADD_PRODUCT_TO_CART_ACTION':
return [...state, {...action.payload.data}];
case 'UPDATE_QUANTITY_FROM_CART_ACTION':
return cart.map(product => {
if (product.attributeID === action.payload.attributeID){
product.quantity++
return {...product}
} else {
return product
}
})
case 'REMOVE_QUANTITY_FROM_CART_ACTION':
return cart.map(product => {
if (product.attributeID === action.payload.attributeID){
product.quantity--
return {...product}
} else {
return product
}
})
case 'TRASH_PRODUCT_FROM_CART_ACTION':
return cart.filter(product => product.attributeID !== action.payload)
default:
return state;
}
}
Here is the cart component who them is connected from redux first:
export function Cart (props)
{
const [productCount, setProductCount] = useState(0)
useEffect(() => {
setProductCount(props.count)
}, [])
if (props.cart.length === 0){
return <div className="home"><p className={'text-center text-green-500'}>Add product to cart.</p></div>
}
return (
<React.Fragment className="home">
<Grid container spacing={3}>
{props.cart.map((item, index) => {
return (
<Grid item xs={6}>
<ProductCartDetails productCount={productCount} key={index} attributes={item}/>
</Grid>
)
})}
</Grid>
</React.Fragment>
)
}
export const CartStore = connect(
(state) => ({
cart: cartSelectors(state),
count: cartCount(state)
})
)(Cart)
This is ProductCartDetails ( The card of the product, and here who action are dispatch )
export default function ProductCartDetails (props){
const [productCount, setProductCount] = useState(0)
const [product, setProduct] = useState([])
const [requestReady, setRequestReady] = useState(false)
useEffect(() => {
axios.get(`product/${props.attributes.productID}`)
.then(({data}) => {
setProduct(data)
setRequestReady(! requestReady)
})
.catch((err) => {
console.log(err)
})
}, [props.productCount])
useEffect(() => {
setProductCount(props.productCount)
}, [props.productCount])
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
width: "100%",
marginTop: 4,
backgroundColor: "#faf7f7",
boxSizing: 'border-box',
},
details: {
display: 'flex',
flexDirection: 'column',
},
content: {
flex: '1',
},
cover: {
width: 151,
height: '100%'
},
}));
const onClickAddMoreQuantity = () => {
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product => {
if (product.attributeID === props.attributes.attributeID){
store.dispatch(
{
type: UPDATE_QUANTITY_FROM_CART_ACTION,
payload: {
attributeID: props.attributes.attributeID
}
}
)
updatedQuantity = true
}
})
if (updatedQuantity === false){
swal({
icon: 'error',
title: 'Cart',
text: 'Product quantity cannot be bigger than the product stock.',
})
}
}
const onClickRemoveQuantityFromCart = () => {
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product => {
if (product.attributeID === props.attributes.attributeID){
store.dispatch(
{
type: REMOVE_QUANTITY_FROM_CART_ACTION,
payload: {
attributeID: props.attributes.attributeID
}
}
)
updatedQuantity = true
}
})
if (updatedQuantity === false){
swal({
icon: 'error',
title: 'Cart',
text: 'Product quantity has not been removed.',
})
}
}
const onClickTrashProductFromCart = () => {
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product => {
if (product.attributeID === props.attributes.attributeID){
store.dispatch(
{
type: TRASH_PRODUCT_FROM_CART_ACTION,
payload: props.attributes.attributeID
}
)
updatedQuantity = true
}
})
if (updatedQuantity === false){
swal({
icon: 'error',
title: 'Cart',
text: 'Product has not been removed.',
})
}
}
const classes = useStyles();
if (productCount !== 0){
return (
<>
<Card className={classes.root}>
<Link to={requestReady ? `/details/${product.slug}` : null}>
<img
className={classes.cover}
src={requestReady ? axios.defaults.baseURL+product.image[0].url+"?h=600" : null}
alt="image cover product cart"
/>
</Link>
<div className={classes.details}>
<CardContent className={classes.content}>
<Typography className="text-center text-gray-700" component="h6" variant="h6">
{requestReady ? product.name : null}
</Typography>
<p className="text-center text-gray-600">
Details Of Product
</p>
<div>
<Typography variant="subtitle1" color="textSecondary">
Category: {requestReady ? product.category.label : null}
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<ProductCartAttributeDetails attributes={props.attributes} />
</Typography>
</div>
</CardContent>
<CardActions>
<button id={requestReady ? product.id : null} onClick={onClickAddMoreQuantity}>
<Add height={10} />Add quantity
</button>
<button>
<Delete height={10} onClick={onClickTrashProductFromCart} />Trash
</button>
<button onClick={onClickRemoveQuantityFromCart}>
<Remove height={10} />Remove quantity
</button>
</CardActions>
</div>
</Card>
</>
)
} else {
return (
<>
<Card className={classes.root}>
<Link to={requestReady ? `/details/${product.slug}` : null}>
<img
className={classes.cover}
src={requestReady ? axios.defaults.baseURL+product.image[0].url+"?h=600" : null}
alt="image cover product cart"
/>
</Link>
<div className={classes.details}>
<CardContent className={classes.content}>
<Typography className="text-center text-gray-700" component="h6" variant="h6">
{requestReady ? product.name : null}
</Typography>
<p className="text-center text-gray-600">
Details Of Product
</p>
<div>
<Typography variant="subtitle1" color="textSecondary">
Category: {requestReady ? product.category.label : null}
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<ProductCartAttributeDetails attributes={props.attributes} />
</Typography>
</div>
</CardContent>
<CardActions>
<button id={requestReady ? product.id : null} onClick={onClickAddMoreQuantity}>
<Add height={10} />Add quantity
</button>
<button>
<Delete height={10} onClick={onClickTrashProductFromCart} />Trash
</button>
<button onClick={onClickRemoveQuantityFromCart}>
<Remove height={10} />Remove quantity
</button>
</CardActions>
</div>
</Card>
</>
)
}
}
And the ProductCartAttributeDetails if needed
export default function ProductCartAttributeDetails({attributes}){
const [attribute, setAttribute] = useState([])
const [requestReady, setRequestReady] = useState(false)
useEffect(() => {
axios.get(`attributes/${attributes.attributeID}`)
.then(({data}) => {
setAttribute(data)
setRequestReady(! requestReady)
})
.catch((err) => {
console.log(err)
})
}, [])
return (
<>
<Typography variant="subtitle1" color="textSecondary">
<p><span className="capitalize">{requestReady ? attribute.attribute : null}</span> : {requestReady ? attribute.value : null}</p>
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<p>Quantity: {requestReady ? attributes.quantity : null}</p>
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<p>Total Price: {requestReady ? attribute.price * attributes.quantity : null}</p>
</Typography>
</>
)
}
Problem was fixed by changing the default index of react js by your own index, for me i have use the index that i receive from my store to be sure them is unique

Material UI React Table Pagination

I want to inquire about Table Pagination in React UI Material.
Here I am trying to implement all the data from the API.
Some of the data that I have successfully implemented is from the API to the Material UI Table.
Bring up data based on request Rows Per Page
Bring up the data comes from the API that I have.
However when I try to implement Pagination, the Data doesn't appear properly from the API.
Example:
When the Component is rendered for the first time, it will display 5 data from the API. But when I tried to move to the next page, only the response from the API was successful, but not the data that appeared.
Here I divide it into several files:
Index Component
Index Container
File Index Component.
import React, { useState } from 'react'
// * Material UI
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
Grid,
TableContainer,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
TablePagination,
CssBaseline
} from '#material-ui/core'
import {
Add
} from '#material-ui/icons'
// * Core Component
import Layout from '#containers/v2/core/Layout'
import InputCategoryComponent from './Input'
import CardCore from '../../core/shared/Card'
import Controls from '../../core/shared/controls'
import { isEmpty } from '#client/libs/utils'
const columns = [
{ id: 'name', label: 'Name', minWidth: 500 },
{ id: 'Actions', label: 'Action', minWidth: 100 }
]
export default function CategoryComponent ({
page = 0,
rowsPerPage = 5,
rowsPerPageOptions = [5, 10, 15, 20, 25],
startDate = '',
endDate = '',
sortBy = 'created_at',
sortDirection = 'desc',
search = '',
totalCount = 0,
items = [],
fetch = () => {},
createPaymentCategory = () => {},
readPaymentCategory = () => {},
updatePaymentCategory = () => {},
deletePaymentCategory = () => {},
handleRowPerPage = () => {},
handlePagination = () => {}
}) {
const [isTable, setTable] = useState(true)
const [alert, setAlert] = useState(false)
const [hashed, setHashed] = useState('')
const [initialModel, setModel] = useState([])
const emptyRows = rowsPerPage - Math.min(rowsPerPage, totalCount - page * rowsPerPage)
const handleTable = (params) => {
setTable(params)
}
const handleAlertOpen = (payload) => {
setHashed(payload)
setAlert(true)
}
const handleChange = (payload) => {
if (isEmpty(payload)) {
setModel({
name: ''
})
setTable(false)
} else {
readPaymentCategory(payload).then((res) => {
setModel(res.data)
setTable(false)
})
}
}
const handleAlertClose = () => {
setAlert(false)
}
const onFinish = () => {
fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
setTable(true)
setModel({
name: ''
})
}
const onDelete = () => {
deletePaymentCategory(hashed).then(() => {
setHashed('')
setAlert(false)
fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
})
}
const onRowChange = (e) => {
handleRowPerPage(e.target.value)
fetch(
0,
e.target.value,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
const onPageChange = (event, newPage) => {
handlePagination(newPage)
fetch(
newPage,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
return (
<Layout>
<CssBaseline />
{isTable && (
<Grid container>
<Grid item sm={12} md={12} lg={12}>
<CardCore
variant='info'
title='Payment Category'
>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<Controls.Button
text='Create'
color='primary'
startIcon={<Add />}
onClick={() => handleChange()}
/>
</Grid>
</Grid>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<TableContainer>
<Table stickyHeader aria-label='sticky table'>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{items.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row) => {
return (
<TableRow hover role='checkbox' tabIndex={-1} key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell align='left'>
<div>
<Controls.Button
text='Edit'
color='inherit'
onClick={() => handleChange(row.hashed_id)}
/>
<Controls.Button
text='Delete'
color='secondary'
onClick={() => handleAlertOpen(row.hashed_id)}
/>
</div>
</TableCell>
</TableRow>
)
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component='div'
count={totalCount}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={onPageChange}
onChangeRowsPerPage={onRowChange}
/>
</Grid>
</Grid>
</CardCore>
</Grid>
</Grid>
)}
<Dialog
open={alert}
onClose={handleAlertClose}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>Are you sure want to delete this?</DialogTitle>
<DialogContent>
<DialogContentText id='alert-dialog-description'>
You wont be able to revert this!
</DialogContentText>
</DialogContent>
<DialogActions>
<Controls.Button
text='Disagree'
color='secondary'
onClick={handleAlertClose}
/>
<Controls.Button
text='Agree'
color='primary'
autoFocus
onClick={onDelete}
/>
</DialogActions>
</Dialog>
{!isTable && (
<InputCategoryComponent
controlTable={handleTable}
initialValues={initialModel}
callBack={onFinish}
createData={createPaymentCategory}
updateData={updatePaymentCategory}
/>
)}
</Layout>
)
}
File Index Container.
import React, { Component } from 'react'
import { mapStateToProps, mapActions } from '#client/store'
import { connect } from 'react-redux'
// * Category Component
import CategoryComponent from '#components/v2/Payment/Category/Index'
class PaymentCategoryContainer extends Component {
constructor (props) {
super(props)
this.state = {
page: 0,
rowsPerPage: 5,
rowsPerPageOptions: [5, 10, 15, 20, 25],
startDate: '',
endDate: '',
sortBy: 'created_at',
sortDirection: 'desc',
search: '',
totalCount: 0,
items: []
}
this.fetch = this.fetch.bind(this)
this.handleRow = this.handleRow.bind(this)
this.handlePage = this.handlePage.bind(this)
}
fetch (page, rowsPerPage, startDate, endDate, sortBy, sortDirection, search) {
this.props.fetchPaymentCategory(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
).then((res) => {
if (res?.status === 200) {
this.setState({
items: res?.data.items,
totalCount: res?.data.totalItems
})
} else {
console.log('error')
}
})
}
handleRow (rowsPerPage) {
this.setState({
rowsPerPage: rowsPerPage
})
const { page, startDate, endDate, sortBy, sortDirection, search } = this.state
this.fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
handlePage (numberOfPage) {
this.setState({
page: numberOfPage
})
const { rowsPerPage, startDate, endDate, sortBy, sortDirection, search } = this.state
this.fetch(
numberOfPage,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
componentDidMount () {
this.fetch(
this.state.page,
this.state.rowsPerPage,
'',
'',
this.state.sortBy,
this.state.sortDirection,
''
)
}
render () {
return (
<CategoryComponent
{...this.props}
{...this.state}
fetch={this.fetch}
handleRowPerPage={this.handleRow}
handlePagination={this.handlePage}
/>
)
}
}
export default connect(
mapStateToProps('paymentCategory'),
mapActions(
'fetchPaymentCategory',
'changeRowPerPage',
'changePagination',
'createPaymentCategory',
'readPaymentCategory',
'updatePaymentCategory',
'deletePaymentCategory'
)
)(PaymentCategoryContainer)
Response data from API:
items: [] => array. totalItems: 0 => int
Are there any mistakes that I missed? or is there a step that i missed ?.
I am following the examples in this section ui material.
Thank you.
I have found where the mistake I made. I shouldn't need to slice() the data. Because I have a params page query so I just need to map() something like this.
return (
<Layout>
<CssBaseline />
{isTable && (
<Grid container>
<Grid item sm={12} md={12} lg={12}>
<CardCore
variant='info'
title='Payment Category'
>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<Controls.Button
text='Create'
color='primary'
startIcon={<Add />}
onClick={() => handleChange()}
/>
</Grid>
</Grid>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<TableContainer>
<Table stickyHeader aria-label='sticky table'>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{items.map((row) => {
return (
<TableRow hover role='checkbox' tabIndex={-1} key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell align='left'>
<div>
<Controls.Button
text='Edit'
color='inherit'
onClick={() => handleChange(row.hashed_id)}
/>
<Controls.Button
text='Delete'
color='secondary'
onClick={() => handleAlertOpen(row.hashed_id)}
/>
</div>
</TableCell>
</TableRow>
)
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component='div'
count={totalCount}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={onPageChange}
onChangeRowsPerPage={onRowChange}
/>
</Grid>
</Grid>
</CardCore>
</Grid>
</Grid>
)}
<Dialog
open={alert}
onClose={handleAlertClose}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>Are you sure want to delete this?</DialogTitle>
<DialogContent>
<DialogContentText id='alert-dialog-description'>
You wont be able to revert this!
</DialogContentText>
</DialogContent>
<DialogActions>
<Controls.Button
text='Disagree'
color='secondary'
onClick={handleAlertClose}
/>
<Controls.Button
text='Agree'
color='primary'
autoFocus
onClick={onDelete}
/>
</DialogActions>
</Dialog>
{!isTable && (
<InputCategoryComponent
controlTable={handleTable}
initialValues={initialModel}
callBack={onFinish}
createData={createPaymentCategory}
updateData={updatePaymentCategory}
/>
)}
</Layout>
)
}
Hope this helps others.

Categories

Resources