I have a problem. I'm lost in the deep forest of reactJs. I'm new here.
I have 8 components which I need to get via clicking on short-name button .
What are the steps.
I select what I need from the first filter and I get short_names and all the components without data.
I don't want to get all the components, i need just 1 component that I'll get by clicking on a short name.
Screenshot here
Here is code of rendering page:
import React, { Component } from 'react';
import { Link } from 'react-router';
import { getAll, getAllRates } from '../actions';
import { MODULE_NAME } from './index';
import { PanelHeader, PanelFooter, LocalFilter } from 'Components';
import locales from 'Shared/locales';
import search from 'Shared/search';
import sortBy from 'Shared/sortBy';
import { AvsProviders, FakProviders, LaaProviders, Laac1Providers,
Laac2Providers, Laac3Providers, MpgProviders, Mpg2Providers } from '../ComponentsProviders';
export default class ListsAccounting extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
search = search(this);
sortBy = sortBy(this);
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAll({ leId: this.state.le_id, name: MODULE_NAME, params: { q, year: this.state.year, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const { id } = event.target;
console.log(id);
}
getData = (leId, id, type, year) => {
getAllRates({ leId, id, type, year, name: MODULE_NAME })
.then(() => this.loadData());
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { limit, totalPages, data } = this.state;
console.log(this);
return (
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-6">
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-filters">
<div className="row no-x-margin">
<div className="col-sm-4 col-xs-6">
<LocalFilter
name="all-providers-leg-entities"
placeholder="le_id"
option="le_id"
value={this.state.le_id}
changeState={this.changeState}
/>
</div>
<div className="col-md-3 col-sm-4 col-xs-6">
<LocalFilter
name="insurance-years"
placeholder="year"
option="year"
value={this.state.year}
changeState={this.changeState}
/>
</div>
</div>
</div>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr className="text-center">
<th>
NAME
</th>
<th>
SHORT_NAME
</th>
<th>
ACTION
</th>
</tr>
</thead>
<tbody>
{
!data.length &&
<tr>
<td colSpan="3" className="text-center">
{locales('no_rows')}
</td>
</tr>
}
{
data.map((row, index) => (
<tr key={`${MODULE_NAME}-${index}`}>
<td>
<h5>{row.type}</h5>
</td>
<td>
{
row.text.map((name, indexText) => (
<span key={name} className="margin-right-10">
<Link
key={row.type}
role="button"
onClick={ () => this.getData(
this.state.le_id,
row.text_id[indexText],
row.type,
row.year,
)}
>
{name}
</Link>
</span >
))
}
</td>
<td className="btn btn-info">
ADD
</td>
</tr>
))
}
</tbody>
</table>
</div>
<PanelFooter
limit={limit}
totalPages={totalPages}
loadData={this.loadData}
/>
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-6">
{ data.type === data.type && data.text_id === data.text_id &&
data.map((row) => {
console.log(row.type);
switch (row.type) {
case 'AVS':
return (
<AvsProviders/>
);
case 'FAK' :
return (
<FakProviders/>
);
case 'LAA':
return (
<LaaProviders/>
);
case 'LAAC1':
return (
<Laac1Providers/>
);
case 'LAAC2':
return (
<Laac2Providers/>
);
case 'LAAC3':
return (
<Laac3Providers/>
);
case 'MPG':
return (
<MpgProviders/>
);
case 'MPG2':
return (
<Mpg2Providers/>
);
default:
return null;
}
})
}
</div>
</div>
</div>
);
}
}
Here is page of 1 of the rendering components:
import React, { Component } from 'react';
import { getAllRates } from '../../actions';
import { PanelHeader } from 'Components';
const MODULE_NAME = 'FAK';
export default class FakProviders extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
componentDidMount() {
this.loadData();
}
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAllRates({ leId: this.props.params.le_id,
id: this.props.params.text_id,
name: MODULE_NAME,
params: { q, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { data } = this.state;
return (
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
search: this.search,
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
<h4>{data.fak_short_name}</h4>
</th>
<th>
<h4>{data.year}</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<h4>fak_rate_ee</h4>
</th>
<th>
<h4>
{data.fak_rate_ee}
</h4>
</th>
</tr>
<tr>
<th>
<h4>fak_rate_er</h4>
</th>
<th>
<h4>
{data.fak_rate_er}
</h4>
</th>
</tr>
</tbody>
</table>
</div>
<div className="panel-footer" />
</div>
);
}
}
Related
Am new to React, and it feels like its very difficult to carry out mathematical calculations with react, Have been trying to add up two values gotten from firebase database but it keeps displaying the values as string and not adding the two values, Please I need help.
{contactObjects[id].gcc} + {contactObjects[id].lcc}
adding this two will only display all as string
E.g
if {contactObjects[id].gcc} is = 10 in firebase datebase and {contactObjects[id].lcc} as = 30
And adding + to the code wont sum up the two values, it will only display them as
10 + 30 which is in string and not 40
Please how can i go about it.
import React, { useState, useEffect } from "react";
import ContactForm from "./ContactForm";
import firebaseDb from "../firebase";
const Contacts = () => {
var [contactObjects, setContactObjects] = useState({});
var [currentId, setCurrentId] = useState("");
useEffect(() => {
firebaseDb.child("contacts").on("value", (snapshot) => {
if (snapshot.val() != null)
setContactObjects({
...snapshot.val(),
});
else setContactObjects({});
});
}, []); // similar to componentDidMount
const addOrEdit = (obj) => {
if (currentId == "")
firebaseDb.child("contacts").push(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
else
firebaseDb.child(`contacts/${currentId}`).set(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
};
const onDelete = (key) => {
if (window.confirm("Are you sure to delete this record?")) {
debugger;
firebaseDb.child(`contacts/${key}`).remove((err) => {
if (err) console.log(err);
else setCurrentId("");
});
}
};
return (
<>
<div className="jumbotron jumbotron-fluid">
<div className="container">
<h1 className="display-4 text-center">Contact Register</h1>
</div>
</div>
<div className="row">
<div className="col-md-5">
<ContactForm {...{ addOrEdit, currentId, contactObjects }} />
</div>
<div className="col-md-7">
<table className="table table-borderless table-stripped">
<thead className="thead-light">
<tr>
<th>Full Name</th>
<th>Mobile</th>
<th>Email</th>
<th>Address</th>
<th>Street</th>
<th>Address</th>
<th>Gcc</th>
<th>Lcc</th>
</tr>
</thead>
<tbody>
{Object.keys(contactObjects).map((id) => {
return (
<tr key={id}>
<td>{contactObjects[id].fullName}</td>
<td>{contactObjects[id].mobile}</td>
<td>{contactObjects[id].email}</td>
<td>{contactObjects[id].address}</td>
<td>{contactObjects[id].street}</td>
<td>{contactObjects[id].gcc}</td>
<td>{contactObjects[id].lcc}</td>
<td>
{contactObjects[id].gcc} +
{contactObjects[id].lcc}
</td>
<td>
<a
className="btn text-primary"
onClick={() => {
setCurrentId(id);
}}
>
<i className="fas fa-pencil-alt"></i>
</a>
<a
className="btn text-danger"
onClick={() => {
onDelete(id);
}}
>
<i className="far fa-trash-alt"></i>
</a>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</>
);
};
export default Contacts;
If I understand correctly, then just parse these values to int. If in DB these are 'string'
{parseInt(contactObjects[id].gcc) + parseInt(contactObjects[id].lcc)}
I've added a search bar to my React-Firebase Dashboard.As a result, the search bar is displayed with the table of clients stored in Cloud Firestore, when I enter a text in the search bar It returns an empty table even if that word exists in the table.
PS: Both of the Results are shown below in screenshots
The table initially rendered
table after writing anything in the search bar
Customer.js
import React, { Fragment, useState } from "react";
import { Avatar } from '#material-ui/core';
import PageTitle from "../../../../layouts/PageTitle";
import { Dropdown, Table } from "react-bootstrap";
import { fire } from "../../../../../fire";
import { firestore } from "../../../../../fire";
import { collection, query, where } from "../../../../../fire";
import App from "../../../../../App";
export default class Recipe extends React.Component {
state = {
searchTerm : "",
Users: []
}
constructor(props){
super(props);
}
searchByTerm = (value) => {
this.setState({searchTerm : value});
}
componentDidMount() {
firestore.collection("Users").get().then((querySnapshot) => {
let User = []
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data().lastn}`);
User.push({
id : doc.id,
data: doc.data()})
});
this.setState({Users : User})
});
}
delete = (id) => {
console.log(id)
firestore.collection("Users").doc(id).delete().then(() => {
console.log("Document successfully deleted!");
this.props.history.push("#")
}).catch((error) => {console.error("Error removing document: ",
error);
});
}
render() {
return (
<Fragment>
<div className="col-12">
<div className="card">
<div className="card-header">
<div className="input-group search-area d-lg-inline-flex d-none mr-
5">
<input
type="text"
className="form-control"
placeholder="Search here"
onChange ={(e) => {
this.searchByTerm(e.target.value);
}}
/>
<div className="input-group-append">
<span className="input-group-text"
>
<svg
width={20}
height={20}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M23.7871 22.7761L17.9548 16.9437C19.5193 15.145 20.4665 12.7982 20.4665 10.2333C20.4665 4.58714 15.8741 0 10.2333 0C4.58714 0 0 4.59246 0 10.2333C0 15.8741 4.59246 20.4665 10.2333 20.4665C12.7982 20.4665 15.145 19.5193 16.9437 17.9548L22.7761 23.7871C22.9144 23.9255 23.1007 24 23.2816 24C23.4625 24 23.6488 23.9308 23.7871 23.7871C24.0639 23.5104 24.0639 23.0528 23.7871 22.7761ZM1.43149 10.2333C1.43149 5.38004 5.38004 1.43681 10.2279 1.43681C15.0812 1.43681 19.0244 5.38537 19.0244 10.2333C19.0244 15.0812 15.0812 19.035 10.2279 19.035C5.38004 19.035 1.43149 15.0865 1.43149 10.2333Z"
fill="#A4A4A4"
/>
</svg>
</span>
</div> </div>
<h4 className="card-title">Customer List </h4>
</div>
<div className="card-body">
<Table responsive className="w-100">
<div id="example_wrapper" className="dataTables_wrapper">
<table id="example" className="display w-100 dataTable">
<thead>
<tr role="row">
<th>Avatar</th>
<th>Email</th>
<th>Firstname</th>
<th>Lastname</th>
<th>PhoneNumber</th>
{/* <th className="pl-5 width200">
Billing Address
</th> */}
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.Users.filter( (val) =>{
const { email = "", firstname = "" } = val;
// console.log(this.state.searchTerm);
if (this.state.searchTerm === "") {
return val;
} else if (
email.toLowerCase().includes(this.state.searchTerm.toLowerCase()) ||
firstname.toLowerCase().includes(this.state.searchTerm.toLowerCase())
) {
return val;
}
}).map(data => {
return (
<tr>
<td> <Avatar className ="rounded-circle img-fluid" src={data.data.avatar}/> </td>
<td>{data.data.email}</td>
<td>{data.data.firstname}</td>
<td>{data.data.datalastname}</td>
<td>{data.data.phonenumber}</td>
<td>
<div
className="btn btn-danger shadow btn-xs sharp" onClick ={this.delete.bind(this, data.id)}
>
<i className="fa fa-trash"></i> </div></td>
</tr>
);
})}
</tbody>
</table>
</div>
</Table>
</div>
</div>
</div>
</Fragment>
);
};
};
Array.prototype.filter callback should be returning a boolean, not the element being iterated over.
This is how I suggest rewriting your filter function: if there is no search term (i.e. falsey) then return true to indicate all elements iterated over should be return, otherwise, return the result of the comparison.
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter((val) => {
const { data: { email = "", firstname = "" } = {} } = val;
if (term) {
return (
email.toLowerCase().includes(term) ||
firstname.toLowerCase().includes(term)
);
}
return true;
})
A slightly more succinct version could be written as follows:
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter(({ data: { email = "", firstname = "" } = {} }) =>
term ? email.concat(firstname).toLowerCase().includes(term) : true
)
Update
After you've stated that you implemented my suggestions and it's still not working I took a closer look at what you are rendering and noticed that in the .map callback you reference each field (email, firstname, etc...) from a data property on each element. Since it seems you are able to render your data when no filter is being applied I'll assume this structure to be correct. As such then, the .filter callback needs to also reference the nested field properties from a data property. I've updated the above code snippets.
I'm working on React booking website, connected to my backend by Rest API using axios and redux. Now I'm trying to show up the personal reservations and rooms for each user loaded, but I can't figure out why my user data aren't visible from my component and I can't reach the user ID by my props.
The code returns this error every time I try to load on componentDidMount the ID: Cannot read property '_id' of null, and my redux state is something like this (with user data nested in "user"):
Here's my redux and dashboard component:
//REDUX
const initialState = {
token: localStorage.getItem("token"),
isAuth: null,
isLoading: false,
user: null,
user_id: "",
};
export default function foo(state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
isLoading: true,
};
case USER_LOADED:
return {
...state,
isAuth: true,
isLoading: false,
user: action.payload,
};
default:
return state;
}
}
//Dashbaord
import React, { Component } from "react";
import { Link } from "react-router-dom";
import moment from "moment";
import { Button, Table, Modal, ModalHeader, ModalBody } from "reactstrap";
import { connect } from "react-redux";
import {
getRooms,
setUserIDRooms,
filteredUserRooms,
deleteRoom,
} from "../actions/itemActions";
import { getReservations, filterReservation } from "../actions/bookAction";
import PropTypes from "prop-types";
import TopCont from "../components/TopCont";
import TabNav from "../components/TabNav";
import Tab from "../components/Tab";
import AddRoom from "../components/AddRoom";
import profile from "../images/unnamed.png";
/*
TODO:
1.fetch stanze by id utente!!
2.fatchare prenotazioni by id!!
*/
class Dashboard extends Component {
state = {
modal: false,
user_id: "",
book_user_id: "",
};
componentDidMount = () => {
this.setState({
user_id: this.props.auth.user._id,
book_user_id: this.props.auth.user._id,
});
console.log(this.state);
};
//Tab
constructor(props) {
super(props);
this.state = {
selected: "Prenotazioni",
};
}
setSelected = (tab) => {
this.setState({ selected: tab });
};
//Modal
toggle = (id) => () => {
this.setState((prevState) => ({
modal: prevState.modal === id ? null : id,
}));
};
closeModal = () => {
this.setState({
modal: !this.state.modal,
});
};
onDeleteClick = (_id) => {
this.props.deleteRoom(_id);
this.closeModal();
};
render() {
const { rooms } = this.props.room;
const { reservations } = this.props.reservation || {};
const { isAuth, user } = this.props.auth;
const DashUnauth = (
<>
<TopCont>
<div className="unauth-dashboard">
<h1>Questa è un'area riservata.</h1>
<Link className="btn-primary" to="/signin">
Accedi
</Link>
<Link className="btn-primary" to="/signup">
Registrati
</Link>
</div>
</TopCont>
</>
);
const DashBasic = (
<>
<div className="dash-cont">
<img src={profile} alt="profilo" className="profile-img" />
<div className="profile-stuff">
<h1>Ciao </h1>
<h3>Bentornato nella tua dashboard.</h3>
<h3>
Da qui puoi accedere alla gestione delle tue prenotazioni e tante
altre funzionalità.
</h3>
<Button onClick={this.onClick}>Aggiorna ID</Button>
</div>
</div>
<div className="tab-cont">
<TabNav
tabs={["Prenotazioni", "Strutture Caricate"]}
selected={this.state.selected}
setSelected={this.setSelected}
>
<Tab isSelected={this.state.selected === "Prenotazioni"}>
<Table hover>
<thead>
<tr>
<th>Struttura</th>
<th>Ospiti</th>
<th>CheckIn</th>
<th>CheckOut</th>
<th>Prezzo /notte</th>
</tr>
</thead>
{reservations.map(
(_id, room_name, ospiti, checkin_date, checkout_date) => (
<tbody>
<tr key={_id}>
<td>{room_name} </td>
<td>{ospiti}</td>
<td>{moment(checkin_date).format("DD/MM/YYYY")}</td>
<td>{moment(checkout_date).format("DD/MM/YYYY")}</td>
<td>Prezzo$</td>
</tr>
</tbody>
)
)}
</Table>
</Tab>
<Tab isSelected={this.state.selected === "Strutture Caricate"}>
<div className="tab-cont-button">
<Button>
<Link to="/profile-upgrade">Diventa Oste</Link>
</Button>
</div>
</Tab>
</TabNav>
</div>
</>
);
const DashPlus = (
<>
<div className="dash-cont">
<img src={profile} alt="profilo" className="profile-img" />
<div className="profile-stuff">
<h1>Ciao </h1>
<h3>Bentornato nella tua DashboardPlus.</h3>
<h3>
Da qui puoi accedere alla gestione delle tue prenotazioni, gestire
i tuoi annunci e tante altre funzionalità.
</h3>
<h1>Il tuo saldo: SPICCIULATO $</h1>
</div>
</div>
<div className="tab-cont">
<TabNav
tabs={["Prenotazioni", "Strutture Caricate", "Aggiungi Struttura"]}
selected={this.state.selected}
setSelected={this.setSelected}
>
<Tab isSelected={this.state.selected === "Prenotazioni"}>
<Table hover>
<thead>
<tr>
<th>Struttura</th>
<th>Luogo</th>
<th>CheckIn</th>
<th>Prezzo /notte</th>
<th>Totale</th>
</tr>
</thead>
{reservations.map(
(_id, room_name, ospiti, checkin_date, checkout_date) => (
<tbody>
<tr key={_id}>
<td>{room_name} </td>
<td>{ospiti}</td>
<td>{moment(checkin_date).format("DD/MM/YYYY")}</td>
<td>{moment(checkout_date).format("DD/MM/YYYY")}</td>
<td>Prezzo$</td>
</tr>
</tbody>
)
)}
</Table>
</Tab>
<Tab isSelected={this.state.selected === "Strutture Caricate"}>
<Table hover>
<thead>
<tr>
<th>Struttura</th>
<th>Luogo</th>
<th>Data Inserimento</th>
<th>Prezzo /notte</th>
<th>Numero Prenotazioni</th>
<th></th>
</tr>
</thead>
{rooms.map(({ _id, name, where, prezzo, upload_date }) => (
<tbody>
<tr key={_id}>
<td>{name}</td>
<td>{where}</td>
<td>{moment(upload_date).format("DD/MM/YYYY")}</td>
<td>{prezzo}$</td>
<td>Prenotazioni</td>
<td>
<Button onClick={this.toggle(_id)}>×</Button>
<Modal
isOpen={this.state.modal === _id}
toggle={this.toggle(_id)}
>
<ModalHeader>Elimina Struttura</ModalHeader>
<ModalBody>
Sei sicuro di voler eliminare questa struttura?
</ModalBody>
<Button onClick={this.onDeleteClick.bind(this, _id)}>
Elimina
</Button>
<Button onClick={this.closeModal}>Annulla</Button>
</Modal>
</td>
</tr>
</tbody>
))}
</Table>
</Tab>
<Tab isSelected={this.state.selected === "Aggiungi Struttura"}>
<AddRoom />
</Tab>
</TabNav>
</div>
</>
);
return <>{isAuth ? (user.userPlus ? DashPlus : DashBasic) : DashUnauth}</>;
}
}
Dashboard.propTypes = {
getRooms: PropTypes.func.isRequired,
getReservations: PropTypes.func.isRequired,
room: PropTypes.object.isRequired,
reservation: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
user_id: state.room.user_id,
book_user_id: state.reservation.book_user_id,
auth: state.auth,
user: state.auth.user,
room: state.room,
reservation: state.reservation,
});
export default connect(mapStateToProps, {
getRooms,
setUserIDRooms,
filteredUserRooms,
deleteRoom,
getReservations,
filterReservation,
})(Dashboard);
Someone could help me??
you forgot a switch for the cases
switch {
// cases
}
I'd like to, when a user deletes on row, for only that row to be deleted. Currently that only happens sometimes. And when you have only two items left to delete, when you click on the delete button, the row's data toggles and replaces itself. It doesn't actually delete.
mainCrud.js - houses the add and delete
crudAdd.js - defines state, event handlers, renders the form itself
crudTable.js - maps pre-defined rows defined in mainCrud.js, renders the table itself
Link to CodeSandbox (tables are under campaigns, dev and news tabs).
Any idea what could be causing this?
MainCrud.js
import React, { useState } from "react";
import CrudIntro from "../crud/crudIntro/crudIntro";
import CrudAdd from "../crud/crudAdd/crudAdd";
import CrudTable from "../crud/crudTable/crudTable";
const MainCrud = props => {
// Project Data
const projectData = [
{
id: 1,
name: "Skid Steer Loaders",
description:
"To advertise the skid steer loaders at 0% financing for 60 months.",
date: "February 1, 2022"
},
{
id: 2,
name: "Work Gloves",
description: "To advertise the work gloves at $15.",
date: "February 15, 2022"
},
{
id: 3,
name: "Telehandlers",
description: "To advertise telehandlers at 0% financing for 24 months.",
date: "March 15, 2022"
}
];
const [projects, setProject] = useState(projectData);
// Add Project
const addProject = project => {
project.id = projectData.length + 1;
setProject([...projects, project]);
};
// Delete Project
const deleteProject = id => {
setProject(projectData.filter(project => project.id !== id));
};
return (
<div>
<section id="add">
<CrudIntro title={props.title} subTitle={props.subTitle} />
<CrudAdd addProject={addProject} />
</section>
<section id="main">
<CrudTable projectData={projects} deleteProject={deleteProject} />
</section>
</div>
);
};
export default MainCrud;
CrudAdd.js
import React, { Component } from "react";
import "../crudAdd/crud-add.scss";
import "../../button.scss";
class CrudAdd extends Component {
state = {
id: null,
name: "",
description: "",
date: ""
};
handleInputChange = e => {
let input = e.target;
let name = e.target.name;
let value = input.value;
this.setState({
[name]: value
});
};
handleFormSubmit = e => {
e.preventDefault();
this.props.addProject({
id: this.state.id,
name: this.state.name,
description: this.state.description,
date: this.state.date
});
this.setState({
// Clear values
name: "",
description: "",
date: ""
});
};
render() {
return (
<div>
<form onSubmit={this.handleFormSubmit}>
<input
name="name"
type="name"
placeholder="Name..."
id="name"
value={this.state.name}
onChange={e => this.setState({ name: e.target.value })}
required
/>
<input
name="description"
type="description"
placeholder="Description..."
id="description"
value={this.state.description}
onChange={e => this.setState({ description: e.target.value })}
required
/>
<input
name="date"
type="name"
placeholder="Date..."
id="date"
value={this.state.date}
onChange={e => this.setState({ date: e.target.value })}
required
/>
<button type="submit" className="btn btn-primary">
Add Project
</button>
</form>
</div>
);
}
}
export default CrudAdd;
CrudTable.js
import React, { Component } from "react";
import "../crudTable/crud-table.scss";
class CrudTable extends Component {
render() {
const props = this.props;
return (
<div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Project Name</th>
<th scope="col">Project Description</th>
<th scope="col">Date</th>
<th scope="col"> </th>
</tr>
</thead>
<tbody>
{props.projectData.length > 0 ? (
props.projectData.map(project => (
<tr key={project.id}>
<td>{project.name}</td>
<td>{project.description}</td>
<td>{project.date}</td>
<td>
<button className="btn btn-warning">Edit</button>
<button
onClick={() => props.deleteProject(project.id)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))
) : (
<tr>
<td>No projects found. Please add a project.</td>
</tr>
)}
</tbody>
</table>
</div>
</div>
);
}
}
export default CrudTable;
This is because you are filtering over projectData. Update your deleteProject method to filter over your React.useState projects variable and it will work.
const deleteProject = id => {
setProject(projects.filter(project => project.id !== id));
};
See code sandbox example here.
I want to render data from API which I render it through for loop but when I'm displaying it to UI, it displays only 1 value.
Specification: - when user upload a text image, API displays text which is present in the image and name, which is the JSON data is an array so I render DetectedText value-form API using for loop but not able to display all value of DetectedText in UI so please tell me where I'm doing wrong please see the below code
import React, { Component } from 'react';
import axios from 'axios'
class Image extends Component {
constructor(props) {
super(props);
this.state = { file: '', imagePreviewUrl: '', selectedOption: '', change: [], response: [], path: [], jsonData: [], dText: [] };
}
handleSubmit(e) {
e.preventDefault();
var byteCode = this.state.imagePreviewUrl.substring((e.target.value).indexOf(',') + 23);
let url = "http://192.168.4.138/MediaAnalysisImage_Amazon/api/DetectText/DetectText";
const data = { "fileByte": byteCode }
const response = axios.post(url, data)
.then(response => {
this.setState({
change: response,
byteArr: response.data.fileByte,
jsonData: response.data.jsondata.replace(/[&\/\\#+()$"~%.'*?<>{}]/g, ''),
path: response.data.jsondata.DetectedText,
});
console.log('json detected data', this.state.jsonData)
const parseData = JSON.parse(response.data.jsondata)
let x = ""
for (let x of parseData) {
const DetectedText = x.DetectedText
this.setState({
dText: DetectedText
})
console.log('setting dtext', this.state.dText)
}
})
}
handleImageChange(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(file)
}
render() {
const img = "data:image/png;base64" + ',' + this.state.byteArr
let { imagePreviewUrl } = this.state;
let $imagePreview = null;
if (imagePreviewUrl) {
$imagePreview = (<img src={imagePreviewUrl} className="img-responsive imgp" />);
} else {
$imagePreview = (<span className="previewText">Please select an Image for Preview</span>);
}
return (
<div className="wrapper">
<h2 className="text-center heading" >Text Recognization</h2>
<div className="container ">
<section className="celeb">
<form className="Fform bg-light mb-4">
<div class="form-group ">
<input className="fileInput"
type="file"
onChange={(e) => this.handleImageChange(e)} class="btn btn-secondary" />
</div>
<button className="btn btn-success"
type="submit"
onClick={(e) => this.handleSubmit(e)}>Upload Image</button>
</form>
<hr></hr>
<div className="row grid">
<div className="col-md-6">
<h3>Input Image</h3>
{$imagePreview}
</div>
<div className="col-md-6">
<h3>Output Image</h3>
<img src={img} className="img-responsive imgp" />
</div>
</div>
<div>
<hr></hr>
<h4>Description </h4>
<table className="table table-hover">
<tr>
<th ><label>Name :- </label></th>
<td>{this.state.dText}</td>
</tr>
</table>
</div>
</section>
</div>
</div>
)
}
}
export default Image;
You may change like this:
this.setState({
dText: parseData.map(x => x.DetectedText),
})
and in your render method:
<td>{ this.state.dText.map((text, index) => <div key={index}>{text}</div>) }</td>