после updateClient()
выполнение Items
получает устаревшее значение
addNewItem() {
if (this.state.newItem._id) {
updateClient(this.state.newItem)
.then(getAllClients().then(Items => {
console.log(Items)
this.setState({ Items: Items })
}))
.then(this.toggleDialog);
} else {
addNewClient(this.state.newItem)
.then(getAllClients().then(Items => {
this.setState({ Items: Items })
}))
.then(this.toggleDialog);
}
}
Это updateClient()
определение
export async function updateClient(data) {
let client = await fetch(
'http://localhost:3100/clients/'+data._id,{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: data.name,
email: data.email,
company: data.company,
address: data.address,
contactNumber: data.contactNumber,
})
})
.then(res => res.json())
return client;
}
и getAllClients()
export async function getAllClients() {
let clients = await fetch('http://localhost:3100/clients/').then(res => res.json())
return clients;
}
это моя начальная настройка состояния
constructor(props) {
super(props);
this.state = {
Items: [],
newItem: {
name: '',
email: '',
company: '',
address: '',
contactNumber: '',
},
newInvoiceId: null,
dialogToggle: false,
}
getAllClients().then(clients => {
this.setState({ Items: clients })
})
}
это моя страница индекса (addNewItem()
)
import React from 'react';
import { Container } from '../utils/mui';
import { Route, Redirect } from 'react-router-dom';
import ClientsTable from "./clientsTable";
import NewClient from './newClient';
import NewInvoice from '../invoices/newInvoice';
import Actions from './actions';
import { getAllClients, getSingleClient, deleteSingleClient, addNewClient, updateClient } from "../api";
class Clients extends React.Component {
constructor(props) {
super(props);
this.state = {
Items: [],
newItem: {
name: '',
email: '',
company: '',
address: '',
contactNumber: '',
},
newInvoiceId: null,
dialogToggle: false,
}
getAllClients().then(clients => {
this.setState({ Items: clients })
})
this.linktoNewInvoice = this.linktoNewInvoice.bind(this);
this.getSingleItem = this.getSingleItem.bind(this);
this.deleteItem = this.deleteItem.bind(this);
this.addNewItem = this.addNewItem.bind(this);
this.newItemValueChange = this.newItemValueChange.bind(this);
this.toggleDialog = this.toggleDialog.bind(this);
}
linktoNewInvoice(data) {
this.setState({ newInvoiceId: data._id });
}
getSingleItem(data) {
getSingleClient(data._id)
.then(singleItem => this.setState({
newItem: {
_id: singleItem[0]._id,
name: singleItem[0].name,
email: singleItem[0].email,
company: singleItem[0].company,
address: singleItem[0].address,
contactNumber: singleItem[0].contactNumber,
}
}))
.then(this.toggleDialog())
}
deleteItem({ _id }) {
deleteSingleClient(_id)
.then(deletedItem => console.log(deletedItem))
.then(() => getAllClients())
.then(Items => this.setState({ Items: Items }));
}
addNewItem() {
if (this.state.newItem._id) {
updateClient(this.state.newItem)
.then(getAllClients().then(Items => {
console.log(Items)
this.setState({ Items: Items })
}))
.then(this.toggleDialog);
} else {
addNewClient(this.state.newItem)
.then(getAllClients().then(Items => {
this.setState({ Items: Items })
}))
.then(this.toggleDialog);
}
}
newItemValueChange(e) {
let newItem = { ...this.state.newItem }
newItem[e.currentTarget.getAttribute('name')] = e.target.value;
this.setState({ newItem: newItem });
}
toggleDialog() {
this.setState({
dialogToggle: !this.state.dialogToggle,
newItem: {
_id: '', name: '', email: '', company: '', address: '', contactNumber: '',
}
})
}
render() {
if (this.state.newInvoiceId != null) {
return <Redirect to={`/invoices/new/${this.state.newInvoiceId}`} />
} else {
return (
<Container>
<Actions addNewItem={this.toggleDialog} />
<Route exact path='/invoice/new' component={NewInvoice} />
<ClientsTable
clients={this.state.Items}
getSingleItem={this.getSingleItem}
deleteItem={this.deleteItem}
/>
<NewClient
dialogToggle={this.state.dialogToggle}
toggleDialog={this.toggleDialog}
newItem={this.state.newItem}
newItemValueChange={this.newItemValueChange}
addNewItem={this.addNewItem}
/>
</Container>
)
}
}
}
export default Clients
и это компонент таблицы для перечисления клиентов
import React, { Component } from 'react';
import {
TableContainer,
Table,
TableHead,
TableBody,
TableRow,
TableCell,
Paper,
IconButton,
Menu,
MenuItem,
MoreVertIcon
} from '../../utils/mui';
export default class ClientsTable extends Component {
constructor(props) {
super(props)
this.state = {
selectedElement:null,
selectedRow: null,
}
this.getMenu = this.getMenu.bind(this)
this.getColumns = this.getColumns.bind(this)
this.getRows = this.getRows.bind(this)
this.handleOptionClick = this.handleOptionClick.bind(this)
this.handleMenuClose = this.handleMenuClose.bind(this)
this.handleEditClient = this.handleEditClient.bind(this)
this.handleDeleteClient = this.handleDeleteClient.bind(this)
}
handleOptionClick(i,row,e){
this.setState({
selectedElement: e.currentTarget,
selectedRow: row
})
}
handleMenuClose(){
this.setState({selectedElement: null});
}
handleEditClient(client){
this.props.getSingleItem(client);
this.handleMenuClose();
}
handleDeleteClient(client){
this.props.deleteItem(client);
this.handleMenuClose();
}
getMenu() {
return (
<Menu open={Boolean(this.state.selectedElement)} onClose={this.handleMenuClose} anchorEl={this.state.selectedElement} >
<MenuItem>Give Invoice</MenuItem>
<MenuItem onClick={()=>{this.handleEditClient(this.state.selectedRow)}}>Edit</MenuItem>
<MenuItem onClick={()=>{this.handleDeleteClient(this.state.selectedRow)}}>Delete</MenuItem>
</Menu>
)
}
render() {
return (
<React.Fragment>
<TableContainer component={Paper} elevation={0}>
<Table aria-label="simple table">
<TableHead>
{this.getColumns()}
</TableHead>
<TableBody>
{this.getRows(this.props, this.handleOptionClick)}
</TableBody>
</Table>
</TableContainer>
{this.getMenu(this.state.selectedElement)}
</React.Fragment>
)
}
getColumns() {
return (
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Company</TableCell>
<TableCell>Email</TableCell>
<TableCell>Contact Number</TableCell>
<TableCell></TableCell>
</TableRow>
)
}
getRows(props,handleOptionClick) {
let TableRows = props.clients.map((row, i) => {
return (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell>{row.company}</TableCell>
<TableCell>{row.email}</TableCell>
<TableCell>{row.contactNumber}</TableCell>
<TableCell align="right">
<IconButton onClick={handleOptionClick.bind(this, i, row)} size="small">
<MoreVertIcon fontSize="inherit" />
</IconButton>
</TableCell>
</TableRow>
)
})
return TableRows;
}
}
и компонент диалога для добавления и редактирования клиентов
import React from 'react';
import {
Dialog,
DialogTitle,
Card,
CardContent,
TextField,
DialogActions,
Button,
Grid,
} from '../../utils/mui';
export default (props) => {
return (
<Dialog open={props.dialogToggle} onClose={props.toggleDialog}>
<Card>
<DialogTitle>Add New Client</DialogTitle>
<CardContent>
<Grid container direction="column" spacing={2}>
<Grid item>
<TextField required={true} className="pb-3" autoComplete="off" value={props.newItem.name} onChange={props.newItemValueChange} inputProps={{ name: 'name' }} label="Client Name" variant="outlined" />
</Grid>
<Grid item>
<TextField required={true} className="pb-3" autoComplete="off" value={props.newItem.email} onChange={props.newItemValueChange} inputProps={{ name: 'email' }} label="Client Email" variant="outlined" />
</Grid>
<Grid item>
<TextField required={true} className="pb-3" autoComplete="off" value={props.newItem.company} onChange={props.newItemValueChange} inputProps={{ name: 'company' }} label="Company Name" variant="outlined" />
</Grid>
<Grid item>
<TextField required={true} className="pb-3" autoComplete="off" value={props.newItem.address} onChange={props.newItemValueChange} inputProps={{ name: 'address' }} label="Address" variant="outlined" />
</Grid>
<Grid item>
<TextField required={true} className="pb-3" type="number" autoComplete="off" value={props.newItem.contactNumber} onChange={props.newItemValueChange} inputProps={{ name: 'contactNumber' }} label="Contact Number" variant="outlined" />
</Grid>
</Grid>
</CardContent>
<DialogActions>
<Button color="primary" onClick={props.toggleDialog}>Close</Button>
<Button color="primary" onClick={props.addNewItem}>Add</Button>
</DialogActions>
</Card>
</Dialog>
)
}
вот мой express код бэкэнда
const express = require('express');
const router = express.Router();
const Client = require('../modals/clients');
// VIEW ALL
router.get('/', (req, res) => {
Client.find({}, (err, clients) => {
if (err) {
res.status(500).send(err)
} else if (clients) {
res.send(clients)
} else {
res.status(500).send(err)
};
});
});
// GET SINGLE
router.get('/:id', (req, res) => {
Client.find({ _id: req.params.id }, (err, client) => {
if (err) {
res.send(err)
} else if (!client) {
res.status(404).send('User not found')
} else if (client) {
res.send(client)
} else {
res.status(500).send('Error')
}
});
});
// ADD NEW
router.post('/', (req, res) => {
let newClient = new Client({
name: req.body.name,
email: req.body.email,
company: req.body.company,
address: req.body.address,
contactNumber: req.body.contactNumber,
});
newClient.save()
.then(client => res.json(client))
.catch(err => res.json({ message: err }));
});
// UPDATE
router.put('/:id', (req, res) => {
Client.findOne({ _id: req.params.id }, (err, oldClient) => {
if (err) {
res.send(err);
} else if (!oldClient) {
res.status(404).send('user not found')
} else if (oldClient) {
if (req.body.name) {
oldClient.name = req.body.name;
}
if (req.body.email) {
oldClient.email = req.body.email;
}
if (req.body.company) {
oldClient.company = req.body.company;
}
if (req.body.contactNumber) {
oldClient.contactNumber = req.body.contactNumber;
}
oldClient.save().then(client => res.send(client));
} else {
res.status(500).send(error);
}
});
});
// DELETE
router.delete('/:id', (req, res) => {
Client.findOne({ _id: req.params.id }, (err, client) => {
if (err) {
res.send(err)
} else if (!client) {
res.sendStatus(404).send('user not found')
} else if (client) {
client.remove().then(deletedClient => res.send(deletedClient))
} else {
res.status(500).send('Error')
}
});
});
// SEARCH WITH NAME
router.get('/search/:name', (req, res) => {
Client.find({ name: { $regex: req.params.name } }, (err, client) => {
if (err) {
res.send(err)
} else if (!client) {
res.status(404).send('user not found')
} else if (client) {
res.send(client)
} else {
res.status(500).send('Error')
}
});
});
module.exports = router;