Web applications in React, Bootstrap, MongoDB, Express/Create a React app with Bootstrap that performs read, create, update, delete operations on a MongoDB database via a Node Express web server
Now we will create the Front end in React-Bootstrap that connects to the Node Express web server and through Rest API acts on the MongoDB database with GET, POST, PUT, DELETE operations on the items in a warehouse:
- 1) In the Documents folder open a terminal and type:
npx create-react-app items-app
- 2) In the items-app folder open a terminal and type to install the Bootstrap css framework:
npm install react-bootstrap bootstrap@5.1.3
- 3) Replace the App.js file with the following:
//App.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Items from './Componenti/Items';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
baseUrl : 'http://localhost:3000/',
};
}
render() {
return (
<div className="container-fluid">
<title>Manage Items</title>
<h1 className="text-center text-primary">Manage Items</h1>
<h2 className="text-center text-secondary">with React, Bootstrap, MongoDB, Express</h2>
<Items baseUrl={this.state.baseUrl} />
</div>
);
}
}
export default App;
- 4) Create a Components sub folder in which to insert the following files:
//items.js
import 'bootstrap/dist/css/bootstrap.min.css';
import Tabella from './Tabella';
import React from 'react';
import ModalView from './ModalView';
class Items extends React.Component
{
constructor(props)
{
super(props);
this.state = {
inputID: "",
inputName: "",
inputQuantity: "",
inputMeasure: "",
show: false,
message: ''
};
this.handleClickNuovo = this.handleClickNuovo.bind(this);
this.handleClickSalva = this.handleClickSalva.bind(this);
this.handleChangeName = this.handleChangeName.bind(this);
this.handleChangeQuantity = this.handleChangeQuantity.bind(this);
this.handleChangeMeasure = this.handleChangeMeasure.bind(this);
this.handleClose = this.handleClose.bind(this);
}
handleChangeName(event)
{
this.setState({
inputName: event.target.value,
});
}
handleChangeQuantity(event)
{
this.setState({
inputQuantity: event.target.value,
});
}
handleChangeMeasure(event)
{
this.setState({
inputMeasure: event.target.value,
});
}
handleClickNuovo(event)
{
this.setState({
inputID: "",
inputName: "",
inputQuantity: "",
inputMeasure: "",
show: false,
});
}
handleClickSalva(event)
{
if (this.state.inputName === "" ||
this.state.inputQuantity === "" ||
this.state.inputMeasure === "" )
{
this.setState({
show: true,
message: 'Tutti i campi devono essere compilati! '
})
}
else if (isNaN(parseFloat(this.state.inputQuantity)))
{
this.setState({
show: true,
message: 'Quantity is a number!'
})
} else
{
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: this.state.inputName,
quantity: this.state.inputQuantity,
measure: this.state.inputMeasure
})
};
fetch(this.props.baseUrl + 'items', requestOptions)
.then(() => console.log('Item created'))
.catch(err => {
console.error(err);
});
this.setState({
show: true,
message: 'Item created!'
})
}
}
handleClose(event)
{
this.setState({
show: false,
});
}
render()
{
return (
<div class="row">
<div className="col-md-12">
<div className="card" >
<div className="card-body">
<h5 className="card-title">Item:</h5>
<div className="input-group mb-3">
<span className="input-group-text">Item name:</span>
<input
type="text"
className="form-control"
value={this.state.inputName}
onChange={this.handleChangeName}
/>
<span className="input-group-text">Quantity:</span>
<input
type="text"
className="form-control"
value={this.state.inputQuantity}
onChange={this.handleChangeQuantity}
/>
<span className="input-group-text">Measure:</span>
<input
type="text"
className="form-control"
value={this.state.inputMeasure}
onChange={this.handleChangeMeasure}
/>
</div>
<button onClick={this.handleClickNuovo} className="btn btn-primary">
New
</button>
<button onClick={this.handleClickSalva} className="btn btn-secondary">
Save
</button>
<button className="btn btn-success">
Update
</button>
<ModalView
message={this.state.message} show={this.state.show} handleClose={this.handleClose}
/>
</div>
</div>
<Tabella baseUrl={this.props.baseUrl} />
</div>
</div>
);
}
}
export default Items;
//Tabella.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import ModalViewEdit from './ModalViewEdit';
class Tabella extends React.Component
{
constructor(props)
{
super(props);
this.state = {
rows: [],
show: false,
editRow:{}
}
this.handleDelete = this.handleDelete.bind(this);
this.handleEdit = this.handleEdit.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleClickEvent = this.handleClickEvent.bind(this);
this.handleClick = this.handleClick.bind(this);
}
componentDidMount()
{
this.handleClick();
document.addEventListener('click', this.handleClickEvent)
}
componentWillUnmount()
{
document.removeEventListener('click', this.handleClickEvent)
}
handleClickEvent(event)
{
this.handleClick();
}
handleClick()
{
fetch(this.props.baseUrl + 'items').then(function (data)
{
return data.json();
}).then(json =>
{
this.setState({
rows: json.map((row) =>
<tr >
<th scope="row" >{row._id}</th>
<td>{row.name}</td>
<td>{row.quantity}</td>
<td>{row.measure}</td>
<td ><button id={row._id} onClick={this.handleEdit} className="btn btn-info">
Edit
</button></td>
<td ><button id={row._id} onClick={this.handleDelete} className="btn btn-danger">
Delete
</button></td>
</tr>),
});
});
}
handleDelete = (e) =>
{
const key = e.currentTarget.getAttribute("id");
fetch(this.props.baseUrl + 'items/' + key,
{
method: 'DELETE',
})
.then(() => console.log('Item deleted: ' + key))
.catch(err =>
{
console.error(err);
});
this.handleClick();
}
handleEdit = (e) =>
{
const key = e.currentTarget.getAttribute("id");
fetch(this.props.baseUrl + 'items/' +key).then(function (data)
{
return data.json();
}).then(json =>
{
this.setState({
editRow: json,
show:true,
});
});
}
handleClose(event)
{
this.setState({
show: false,
editRow:{}
});
}
render()
{
return (
<>
<table className="table table-striped" >
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Quantity</th>
<th scope="col">Measure</th>
</tr>
</thead>
<tbody>
{this.state.rows}
</tbody>
</table>
{this.state.show && <ModalViewEdit
baseUrl={this.props.baseUrl} editRow={this.state.editRow} show={this.state.show} handleClose={this.handleClose}
/>}
</>
);
}
}
export default Tabella;
- 5) In the terminal type:
npm start
and use the program.