Why is async await very slow? - mysql

I want to make selector for the user to select name of section, and according to what he select, view the section types in another selector, then when he select the section type display the students in a table.
I write code and get the data true but because i use (async..await) so the project get very slow and then closed.
What's the wrong?
function Teacher() {
const [data1, setData1] = useState([]);
const [data2, setData2] = useState([]);
const [data3, setData3] = useState([]);
const [SectionName, setSectionName] = useState('بستان');
const [Type, setType] = useState('أ');
useEffect(() => {
async function getName() {
await Axios
.get(`http://localhost:3003/getSectionsName`)
.then(result => setData1(result.data));
}
getName()
}, []);
const nameSelector = (
<select className="custom-select" onChange={(e) => {
const selectedSectionName = e.target.value;
setSectionName(selectedSectionName);
}}>
{data1.map((item) =>
<option key={item.id} value={item.SectionName}>
{item.SectionName}
</option>
)}
</select>
)
async function typeSelector() {
await Axios.put(`http://localhost:3003/getSectionTypes`, { SectionName: SectionName }).then(result => setData2(result.data))
}
const typeSelect = (
typeSelector(),
<select className="custom-select" onChange={(e) => {
const selectedSectionType = e.target.value;
setType(selectedSectionType);
}}>
{data2.map((item) =>
<option key={item.id}>
{item.Type}
</option>
)}
</select>
)
function student() {
Axios.put(`http://localhost:3003/getStudents`, { Type: Type, SectionName: SectionName }).then(result => setData3(result.data))
}
const studentTable = (
student(),
<table className="table" >
<thead className="thead-dark">
<tr>
<th scope="col">الطلاب</th>
</tr>
</thead>
<tbody>
{data3.map(item => {
return <tr key={item.Id}>
<td>{item.FullName}</td>
</tr>
})}
</tbody>
</table>
)
return (
<div className="container p-2">
<h4> اختر الصف </h4>
{nameSelector}
<br />
<h4> اختر الشعبة </h4>
{typeSelect}
<br /><br />
<h4>
{studentTable}
</h4>
</div>
)
}
export default Teacher;

async function typeSelector() {
await Axios.put(`http://localhost:3003/getSectionTypes`, { SectionName: SectionName }).then(result => setData2(result.data))
}
const typeSelect = (
typeSelector(),
...
is plain wrong - it means you're calling typeSelector() with the comma sequencing operator as a side effect of rendering the component, and likely end up in an infinite render loop. This would happen with a non-async typeSelector() function too.
You will need to wrap those fetch calls within suitable useEffect() hooks, maybe like so (I took the liberty of also extracting the components into, well, components.)
function StudentTable({ students }) {
return (
<table className="table">
<thead className="thead-dark">
<tr>
<th scope="col">الطلاب</th>
</tr>
</thead>
<tbody>
{students.map((item) => {
return (
<tr key={item.Id}>
<td>{item.FullName}</td>
</tr>
);
})}
</tbody>
</table>
);
}
function NameSelector({ sections }) {
return (
<select
className="custom-select"
onChange={(e) => setSectionName(e.target.value)}
>
{sections.map((item) => (
<option key={item.id} value={item.SectionName}>
{item.SectionName}
</option>
))}
</select>
);
}
function TypeSelect({ types }) {
return (
<select
className="custom-select"
onChange={(e) => setType(e.target.value)}
>
{types.map((item) => (
<option key={item.id} value={item.id}>
{item.Type}
</option>
))}
</select>
);
}
function Teacher() {
const [sections, setSections] = useState([]);
const [types, setTypes] = useState([]);
const [students, setStudents] = useState([]);
const [sectionName, setSectionName] = useState("بستان");
const [type, setType] = useState("أ");
// Load sections on mount
useEffect(() => {
Axios.get(
`http://localhost:3003/getSectionsName`,
).then((result) => setSections(result.data));
}, []);
// Load types based on selected section
useEffect(() => {
Axios.put(`http://localhost:3003/getSectionTypes`, {
SectionName: sectionName,
}).then((result) => setTypes(result.data));
}, [sectionName]);
// Load students based on section and type
useEffect(() => {
Axios.put(`http://localhost:3003/getStudents`, {
Type: type,
SectionName: sectionName,
}).then((result) => setStudents(result.data));
}, [sectionName, type]);
return (
<div className="container p-2">
<h4> اختر الصف </h4>
<NameSelector sections={sections} />
<br />
<h4> اختر الشعبة </h4>
<TypeSelect types={types} />
<br />
<br />
<h4>
<StudentTable students={students} />
</h4>
</div>
);
}
export default Teacher;

Try useEffect() that has a dependency sectionName. When it changes, then you will call typeSelector() and student().
const [data1, setData1] = useState([]);
const [data2, setData2] = useState([]);
const [data3, setData3] = useState([]);
const [sectionName, setSectionName] = useState('بستان');
const getName = async () => {
const data = await Axios.get(`http://localhost:3003/getSectionsName`);
setData1(data);
};
const typeSelector = async () => {
const data = await Axios.put(`http://localhost:3003/getSectionTypes`, {
SectionName: SectionName
});
setData2(data);
};
const student = async () => {
const data = Axios.put(`http://localhost:3003/getStudents`, {
Type: Type,
SectionName: SectionName
});
setData3(data);
};
useEffect(() => {
getName();
}, []);
useEffect(() => {
typeSelector();
student();
}, [sectionName]);

Related

Getting a console error called "data.map" is not a function

I am trying to build a table based of an Axios get call. And when I'm trying to create the rows for my table, I'm getting an error called "data.map is not a function".
Here's my Dashboard main function:
import axios from "axios"
import { useEffect, useState } from 'react';
import Navbar from "../components/tenantComponents/NavBar"
import Table from '../components/tenantComponents/Table'
export default function OwnerDashboard2(){
const [ownerData, setTenantData] = useState([])
const [dataTable, setDataTable] = useState([]);
useEffect(() => {
axios.get('https://t00axvabvb.execute-api.us-west-1.amazonaws.com/dev/propertiesOwner?owner_id=100-000003')
.then(res => setDataTable(res.data))
console.log(dataTable);
axios.get('https://t00axvabvb.execute-api.us-west-1.amazonaws.com/dev/propertiesOwner?owner_id=100-000003')
.then(res => setTenantData(res.data))
.catch(err => console.log(err))
});
const column = [
{ heading: 'Addresses', value:'result.address'},
{ heading: 'Property Type', value:'result.property_type'},
{ heading: 'Rent', value:'result.listed_rent'},
]
return(
<div className="OwnerDashboard2">
<div>
{ownerData.length !== 0 && <h3 style={{paddingLeft: "7rem", paddingTop:"2rem"}}>{ownerData.result[0].owner[0].owner_first_name + " " +ownerData.result[0].owner[0].owner_last_name}</h3> }
<h8 style={{paddingLeft: "7rem", paddingTop:"2rem"}}>Owner</h8>
<Navbar/>
</div>
<div>
<Table data={dataTable} column={column} />
</div>
</div>
)
}
My Table Function:
import './table.css'
const Table = ({ data, column }) => {
return (
<table>
<thead>
<tr>
{column.map((item, index) => <TableHeadItem item={item} />)}
</tr>
</thead>
<tbody>
{data.map((item, index) => <TableRow item={item} column={column} />)}
</tbody>
</table>
)
}
const TableHeadItem = ({ item }) => <th>{item.heading}</th>
const TableRow = ({ item, column }) => (
<tr>
{column.map((columnItem, index) => {
return <td>{item[`${columnItem.value}`]}</td>
})}
</tr>
)
export default Table
The issue is in the tbody with data.map but I'm not sure what's wrong as I define my TableRow. I would greatly appreciate any help!

Conditional rendering inside map function ReactJs

I know there's similar thread already but i'm a total newbie and i can't work it. I'm not able include conditional rendering after my map function, do i need some sortf of HTML-tag inbetween?
const renderTableData = () => {
let id = 1;
const activeButton = () => {
}
return (
<tr>
{days.map((val) => (
<td>
{timeSlot.map((n, i) => (
// if(freeSlotsList.includes(id)){ THIS CODE SNIPPET
// return (<h1>Testing</h1> DON'T WORK
// )}
<button id={id++} className={activeButton}> {n} {id}</button>
))}
</td>
))}
</tr>
);
};
EDIT:
i can't seem to access my freeSlotsList, it looks like this
const [freeSlotsList, setFreeSlotsList] = useState([])
useEffect(() => {
Axios.post('http://localhost:3001/api/get/week1/ex').then((response) => {
setFreeSlotsList(response.data)
})
}, [])
Try this, You need to wrap your code into {} if you want to write js code. As () will simply return that as jsx.
const renderTableData = () => {
let id = 1;
const activeButton = () => {
}
return (
<tr>
{days.map((val) => (
<td>
{timeSlot.map((n, i) => {
if(freeSlotsList.includes(id)){
return (<h1>Testing</h1>
)}
return <button id={id++} className={activeButton}> {n} {id}</button>
)}}
</td>
))}
</tr>
);
};

change value of input field react

I have an input field in which I am pre populating the value of, with the value from the DB. it is a record that already exists, in which I would like to edit. The input field however, is not letting me edit the field. Please find it below:
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useHistory } from "react-router-dom";
const EditServicesPage = () => {
const history = useHistory()
const [myData, setMyData] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [showEditButton, setShowEditButton] = useState(false);
const [fields, setFields] = useState({
updatedByCNUM: "",
content: "",
site: ""
})
var idFromListServicesPage = history.location.state.id
console.log("22: " + idFromListServicesPage)
useEffect(() => {
axios
.post('/getDocToEdit', {id : idFromListServicesPage})
.then((res) => {
console.log("line 28 esp.js: " + res.data)
setMyData(res.data);
setIsLoading(true);
})
.catch((error) => {
// Handle the errors here
console.log(error);
})
.finally(() => {
setIsLoading(false);
});
}, []);
const deleteById = (id) => {
console.log(id);
axios
.post(`/deleteDoc`, { id: id })
.then(() => {
console.log(id, " worked");
window.location = "/admin/content";
})
.catch((error) => {
// Handle the errors here
console.log(error);
});
};
const handleInputChange = e => setFields(f => ({...f, [e.target.name]: e.target.value}))
const editById = (id, site, content, updatedByCNUM) => {
console.log(id, site, content, updatedByCNUM);
axios
.post(
'/editDoc',
({
id: id,
location: site,
content: content,
updatedByCNUM: updatedByCNUM
})
)
.then(() => {
console.log(id, " worked");
window.location = "/admin/content";
})
.catch((error) => {
console.log(error);
});
};
const onClickEdit = (e, _id) => {
e.preventDefault();
var site = document.getElementById("site").value;
var content = document.getElementById("content").value;
var updatedByCNUM = document.getElementById("updatedByCNUM").value;
console.log(site, content, updatedByCNUM)
editById(_id, site, content, updatedByCNUM);
};
const onTyping = (value) => {
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
return (
<table id="customers">
<h1>Edit Services Page</h1>
<tr>
<th>site</th>
<th>content</th>
<th>updatedByCNUM</th>
<th>Actions</th>
</tr>
<tr>
<td>
<input
// ref={site.ref}
type="text"
value={myData.site}
onInput={(e) => onTyping(e.target.value)}
onChange={handleInputChange}
placeholder={myData.site}
name="site"
id="site"
/>{" "}
{/* <input
type="text"
placeholder={site}
onChange={(e) => onTyping(e.target.value)}
name="site"
id="site"
/> */}
</td>
<td>
<input
// ref={content.ref}
type="text"
value={myData.content}
onInput={(e) => onTyping(e.target.value)}
onChange={handleInputChange}
placeholder={myData.content}
name="content"
id="content"
/>
</td>
<td>
<input
type="text"
placeholder={myData.updatedByCNUM}
name="updatedByupdatedByCNUMhide"
id="updatedByupdatedByCNUMhide"
readOnly
/>{" "}
</td>
<td>
{/* <input type="hidden" placeholder={myData.updatedByCNUM} name="updatedByCNUM" id="updatedByCNUM" value={updatedByCNUM}/>{" "} */}
</td>
<td>
<button
onClick={(e) => {
e.preventDefault();
deleteById(idFromListServicesPage);
}}
disabled={isLoading}
>
Delete
</button>
<button
onClick={(e) => {
e.preventDefault();
editById(idFromListServicesPage);
}}
>
Edit
</button>
{showEditButton && (
<button onClick={(e) => onClickEdit(e, idFromListServicesPage)}>Submit Edit</button>
)}
</td>
</tr>
</table>
);
};
export default EditServicesPage;
showButton:
const onTyping = (value) => {
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
when I try to type into the input field, it doesn't allow me to type, but keeps the pre existing value there already. how can I fix this?
You need a state which has the initial values from the DB
const [data, setData] = useState({
site: newData.site || "",
content: newData.content || "",
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setData((currentData) => ({ ...currentData, [name]: value }));
};
return (
// .....
<input
// ref={site.ref}
type="text"
value={data.site} // use data.site here instead of the newData
onChange={handleInputChange}
placeholder={myData.site}
name="site"
id="site"
/>
// .....
);
Just add setMyData like this:
const onTyping = (name, value) => {
setMyData({ ...myData, [name]: value });
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
And
onInput={(e) => onTyping(e.target.name, e.target.value)}

How to disable a button until all the fields are filled in a textfield

I have a table in a modal whose code looks like this.
<div>
<Table>
<tbody>
{props.data.map((p) => <>
<tr>
<th> STC </th>
<th> Edit Text</th>
</tr>
<tr index={p}>
<td key={p.stc}><h3>{p.stc}</h3></td>
<td >
<TextField name={p.stc} type="text" value={p.readValue} onChange={handleChange} required={true} size="small" label="Required" variant="outlined" />
</td>
</tr>
</>)}
</tbody>
</Table>
<div >
<Button disabled={inputState.disable} className="buttonStyle" onClick={(e) => submit()}>SUBMIT</Button>
<Button onClick={handleClose}>CANCEL</Button>
</div>
</div>
And their corresponding functions and declarations as below -
const [formInput, setFormInput] = useReducer(
(state, newState) => ({ ...state, ...newState }),
);
const [inputState, setInputState] = useState({disable: true});
const handleOpen = (e) => {
setOpen(true);
};
const handleClose = () => {
window.location.reload(false);
setOpen(false);
};
const [readValue, writeValue] = useState("");
const submit = (e) => {
console.log("Submitted!")
handleClose();
}
const handleChange = (event) => {
const newValue = event.target.value;
writeValue(event.target.value)
setInputState({disable: event.target.value===''})
}
I want to -
disable the buttons until and unless all the TextFields are filled.
In handleClose(), is there any alternate solution for clearing the values of TextFields in stead of window.reload?
The format looks like the picture I'm attaching below-
enter image description here
import React, { useState } from "react";
import "./style.css";
export default function App() {
const textFields = ["field1", "field2"];
const [inputValue, setInputValue] = useState({});
const [buttonDisabled, setButtonDisabled] = useState(true);
const validateButton = accInputs => {
let disabled = false;
textFields.forEach(field => {
if (!accInputs[field]) {
disabled = true;
}
});
return disabled;
};
const handleChange = ({ currentTarget }) => {
const { name, value } = currentTarget;
const inputObj = {};
inputObj[name] = value;
const accInputs = { ...inputValue, ...inputObj };
setInputValue(accInputs);
setButtonDisabled(validateButton(accInputs));
};
const handleSubmit = () => {
console.log("submit clicked");
};
const handleCancel = () => {
const inputObj = {};
textFields.forEach(field => {
inputObj[field] = "";
});
setInputValue(inputObj);
};
return (
<div>
<table border="1px">
<tr>
<th> STC </th>
<th> Edit Text</th>
</tr>
{textFields.map(field => {
console.log("rendered");
return (
<tr>
<td>
<h3>p.stc</h3>
</td>
<td>
<input
placeholder="required *"
value={inputValue[field]}
name={field}
onChange={handleChange}
/>
</td>
</tr>
);
})}
</table>
<input type="submit" disabled={buttonDisabled} onClick={handleSubmit} />
<input type="submit" onClick={handleCancel} value="cancel" />
</div>
);
}
can be easily achieved with the above code. Please refer working example here
updated to add second point aswell.

Delete a Row using Fetch API Use Effect - ReactJS

am trying to delete a row based on product code entered, i have 2 functions, one is for search and another is for delete..
Search Function
const handleName = e => {
const idAddProducts = e.target.value;
e.preventDefault();
pnName({ ...poName, idaddproducts: idAddProducts });
handleTable(idAddProducts);
// handleSubmit(idAddProducts);
console.log(poName);
};
async function handleTable(idAddProducts) {
const id = poName.idaddproducts;
const res = await fetch(
"http://localhost:4000/productslist/" + idAddProducts
);
const data = await res.json();
pnName(data.data);
console.log(data.data);
}
useEffect(() => {
handleTable();
}, []);
Another one is Delete Function
const handleN = e => {
const idAddProducts = e.target.value;
e.preventDefault();
pnName({ ...poName, idaddproducts: idAddProducts });
handleSubmit(idAddProducts);
console.log(poName);
};
async function handleSubmit(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/delete/" + idAddProducts
);
const data = await res.json();
pnName(data.data);
console.log(data.data);
}
useEffect(() => {
handleSubmit();
}, []);
Here is the Rendering Part where i map the searched result
<TableBody>
{poName && poName.length ? (
poName.map(row => (
<TableRow key={row.idaddproducts}>
<TableCell component="th" scope="row">
{row.idaddproducts}
</TableCell>
<TableCell component="th" scope="row">
{row.productName}
</TableCell>
<TableCell align="right">{row.productId}</TableCell>
<TableCell align="right">{row.productBrand}</TableCell>
<TableCell align="right">{row.productQuantity}</TableCell>
<TableCell align="right">{row.productPrice}</TableCell>
<TableCell align="right">{row.productType}</TableCell>
</TableRow>
))
) : (
<span>Not Found</span>
)}
</TableBody>
</Table>
</TableContainer>
<div style={{ paddingBlockEnd: "0px" }}>
<Fab color="secondary" aria-label="edit" onClick={handleN}>
<EditIcon />
</Fab>
</div>
So when i add the handleSubmit function directly in to handleName, its getting deleted as i type, so i had to create seperate function as HandleN and call handle submit so that when i click button it should execute,
instead sql throws as Error:
ER_TRUNCATED_WRONG_VALUE: Truncated incorrect DOUBLE value:
'undefined'
or
Error: ER_TRUNCATED_WRONG_VALUE: Truncated incorrect DOUBLE value:
'[object]%20[object]'
Any help ?
export default function DeleteProductsForm() {
const initialState = {
idaddproducts: "",
productName: "",
productId: "",
productBrand: "",
productQuantity: "",
productPrice: "",
productType: ""
};
const [values, setValues] = React.useState(initialState);
const handleName = e => {
const idAddProducts = e.target.value;
console.log(idAddProducts);
e.preventDefault();
setValues({ ...values, [e.target.name]: idAddProducts });
handleList1(idAddProducts);
console.log(values);
};
const handleN = e => {
const idAddProducts = values.idaddproducts;
console.log(idAddProducts);
e.preventDefault();
setValues({ ...values, [e.target.name]: idAddProducts });
handleList(idAddProducts);
console.log(values);
};
async function handleList1(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/" + idAddProducts
);
const data = await res.json();
setValues(data.data);
console.log(data.data);
}
useEffect(() => {
handleList1();
}, []);
async function handleList(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/delete/" + idAddProducts
);
const data = await res.json();
setValues(data.data);
console.log(data.data);
}
useEffect(() => {
handleList();
}, []);
const classes = useStyles();
return (
<form className={classes.root} noValidate autoComplete="off" align="center">
<div className={classes.formGroup}>
<FormControl>
<Input
type="search"
label="Product ID"
variant="outlined"
size="small"
placeholder="Enter Product Code"
value={values.idaddproducts}
name="idaddproducts"
onChange={e => handleName(e)}
/>
</FormControl>
<Button onClick={e => handleN(e)}>Click</Button>
{values && values.length ? (
values.map(row => <h5 key={row.idaddproducts}>{row.productName}</h5>)
) : (
<h5>Not Found</h5>
)}
</div>
</form>
);
}
if i delete handleList1 function it works fine.. but it wont display data