I am new to React and I don't know how to overcome the below situation.
Let say I have to display a table.In Table <td> i have one dropdown which I got from my child component.And also have some <div> next to the dropdown.
So,for each dropdown change, i have to bind some html into that <div>.Below line is working for very first dropdown change.
ReactDOM.render(myHtml, document.getElementById(myID));
So For a second time it is not render the new html.
Kindly correct me If I did anything wrong and give me some suggestion to overcome the above issue.
Thanks in Advance.
class Home extends Component{
state = {
tableDetails:'',
};
LoadTableDetails = () => {
const getUrl = "Some API Url";
let dd= fetch(getUrl);
dd.then(response => {
return response.json();
}).then(items => {
var body = this.getTableBody(items);
this.setTableDetails(body);
});
}
getTableBody(items){
let body ;
if(items != null){
body = items.map((folder,index) =>
<tr key={index}>
<td>{folder.FolderName}</td>
<td>
<MyDropDown fileNames={folder.FileNames} folderFiles={folder.FolderFiles} id={folder.FolderName.replace(/ /g,'_')} setSelectedFile = {this.setSelectedFile}/> // Here I get dropdown selected value and see setSelectedFile method
</td>
<td>
<div id={folder.FolderName.replace(/ /g,'_')}>
////I need some html here based on the above dropdown change
</div>
</td>
<td></td>
</tr>
);
}
return folderItems;
}
setTableDetails(body){
let dd = (<div className="container" >
<h2 class="text-center">Server Details</h2>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Folder</th>
<th scope="col">Config Files</th>
<th scope="col">Config Section</th>
<th scope="col">App Settings</th>
</tr>
</thead>
<tbody>
{body}
</tbody>
</table>
</div>);
this.setState({tableDetails:dd});
}
setSelectedFile = (val) =>{
const getUrl = 'my url';
let loadItems = fetch(getUrl);
loadItems.then(response=>{
return response.json();
}).then(data=>{
let configHtml = (
<div>
<MyDropDown fileNames={data} id={val.id + path.replace('\\','_').replace('/\//g','_')} path={path} setSelectedFile = {this.getConfigSectionDetails}/>
<div className="mt-4" id={val.id + path.replace('\\','_').replace('/\//g','_')}>
</div>
</div>
);
let id = val.id; //This is the id where my new
ReactDOM.render(configHtml, document.getElementById(id)); //this line is working for my first dropdown change.If I change the dropdown again then it is not rerenered
});
}
render(){
return (
<div class="mt-4">
<div class="input-group-append">
<button class="btn btn-info" type="button" onClick={this.LoadTableDetails}>Load Table Details</button>
</div>
{this.state.tableDetails}
</div>
);
}
}
export default Home;
I got my Answer.We have to use our states to update the values and not html.
class Home extends Component{
state = {
tableDetails:'',
dropdownDetails:''
};
LoadTableDetails = () => {
const getUrl = "Some API Url";
let dd= fetch(getUrl);
dd.then(response => {
return response.json();
}).then(items => {
this.setState({
tableDetails:items
});
});
}
getTableDetails = (items)=>{
return (<div className="container" >
<h2 class="text-center">Server Details</h2>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Folder</th>
<th scope="col">Config Files</th>
<th scope="col">Config Section</th>
<th scope="col">App Settings</th>
</tr>
</thead>
<tbody>
{
items.map((folder,index) =>{
return (<tr key={index}>
<td>{folder.FolderName}</td>
<td>
<MyDropDown fileNames={folder.FileNames} folderFiles={folder.FolderFiles} id=index setSelectedFile ={this.setSelectedFile}/>
</td>
<td>
<div>
{this.getConfigHtml(this.state.dropdownDetails)}
</div>
</td>
<td></td>
</tr>)
})
}
</tbody>
</table>
</div>);
}
getConfigHtml =(val)=>{
return (
<div>
<MyDropDown fileNames={val.data} path={val.path} setSelectedFile = {this.getConfigSectionDetails}/>
</div>
);
}
setSelectedFile = (val) =>{
const getUrl = 'my url';
let loadItems = fetch(getUrl);
loadItems.then(response=>{
return response.json();
}).then(data=>{
let val={
data:data,
path:val.path
};
this.setState({dropdownDetails:val});
});
}
render(){
return (
<div class="mt-4">
<div class="input-group-append">
<button class="btn btn-info" type="button" onClick={this.LoadTableDetails}>Load Table Details</button>
</div>
{this.getTableDetails(this.state.tableDetails)}
</div>
);
}
}
export default Home;
Related
import React, { useState, useEffect } from "react";
import Axios from "axios";
import { Navigate, Link } from "react-router-dom";
import gravatarUrl from "gravatar-url";
import "../assets/css/profile.css";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import API from "../backend";
import { isAutheticated } from "../auth";
let img;
const Profile = () => {
// setting values
const [data, setData] = useState({
email: "",
name: "",
city: "",
state: "",
phone: "",
country: "",
role: "",
reg: "",
error: "",
success: "",
});
// state to know if someone clicked on the edit button
const [edit, setEdit] = useState(false);
// handaling onchange event
const onHandleChange = (val) => (event) => {
setUpdate({ ...update, [val]: event.target.value });
};
// Updating the new value from input
const [update, setUpdate] = useState({
name: "",
city: "",
state: "",
phone: "",
country: "",
error: "",
});
// state to check if someone click on submit
const [didSubmit, setDidSubmit] = useState(false);
// destructuring values from data (useState)
const { email, name, city, state, phone, country, reg, role } = data;
// destructuring token from localstorage
const { token } = isAutheticated();
// dataObject for api call
const dataType = {
headers: {
authorization: `Bearer ${token}`,
},
};
// get api call
const axiosGetCall = async () => {
try {
const res = await Axios.get(`${API}/user/profile`, dataType);
// seting image
img = gravatarUrl(res.data.user.email, { size: 200 });
// set data
setData({
...data,
email: res.data.user.email,
name: res.data.user.name,
city: res.data.user.city,
state: res.data.user.state,
phone: res.data.user.phone,
country: res.data.user.country,
role: res.data.user.role,
reg: res.data.user.createdAt,
success: true,
});
} catch (error) {
console.log(`error log: `, error);
setData({
...data,
error: error.response.data.error,
success: false,
});
}
};
// post call/update
const axiosUpdateCall = async () => {
// token
const { token1 } = isAutheticated();
// new dataObject for post call
const dataToken = {
headers: {
authorization: `Bearer ${token1}`,
},
};
try {
const res = await Axios.post(`${API}/user/profileEdit`, dataToken);
console.log(`res:`, res);
} catch (error) {
console.log(`error log: `, error);
setData({
...data,
error: error.response.data.error,
success: false,
});
}
};
// For get api call
useEffect(() => {
axiosGetCall();
}, []);
// for post api call if some clicked on submit
useEffect(() => {
if (didSubmit) {
axiosUpdateCall();
}
}, [didSubmit]);
// prevent default
const onSubmit = (event) => {
event.preventDefault();
setDidSubmit(true);
};
// Normal profile HTML CODE
const profileMain = () => {
return (
<div className="container bootdey flex-grow-1 container-p-y">
<div className="media align-items-center py-3 mb-3">
<img src={img} alt="" className="d-block ui-w-100 rounded-circle" />
<div className="media-body ml-4">
<h4 className="font-weight-bold mb-0">
{name.charAt(0).toUpperCase() + name.slice(1)}
</h4>
<button
onClick={() => {
setEdit(true);
}}
className="btn btn-primary btn-sm"
>
Edit
</button>
<Link to="" className="btn btn-primary btn-sm">
Go back
</Link>
</div>
</div>
<div className="card mb-4">
<div className="card-body">
<table className="table user-view-table m-0">
<tbody>
<tr>
<td>Registered:</td>
<td>{reg.slice(0, 10)}</td>
</tr>
<tr>
<td>Verified:</td>
<td>
<span className="fa fa-check text-primary"></span> No
</td>
</tr>
<tr>
<td>Role:</td>
<td>{role.charAt(0).toUpperCase() + role.slice(1)}</td>
</tr>
<tr>
<td>Status:</td>
<td>
<span className="badge badge-outline-success">Active</span>
</td>
</tr>
</tbody>
</table>
</div>
<hr className="border-light m-0" />
</div>
<div className="card">
<hr className="border-light m-0" />
<div className="card-body">
<h6 className="mt-4 mb-3">Personal Details:</h6>
<table className="table user-view-table m-0">
<tbody>
<tr>
<td>Full Name:</td>
<td>{name.charAt(0).toUpperCase() + name.slice(1)} </td>
<td></td>
</tr>
<tr>
<td>Email:</td>
<td>{email}</td>
</tr>
<tr>
<td>Phone:</td>
<td>{phone}</td>
</tr>
<tr>
<td>City:</td>
<td>{city}</td>
</tr>
<tr>
<td>State:</td>
<td>{state}</td>
</tr>
<tr>
<td>Country:</td>
<td>{country}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
);
};
// Profile when someone clicked on edit
const profileEdit = () => {
return (
<>
<div className="container bootdey flex-grow-1 container-p-y">
<div className="media align-items-center py-3 mb-3">
<img src={img} alt="" className="d-block ui-w-100 rounded-circle" />
<div className="media-body ml-4">
<h4 className="font-weight-bold mb-0">
{name.charAt(0).toUpperCase() + name.slice(1)}
</h4>
</div>
</div>
<div className="card mb-4">
<div className="card-body">
<table className="table user-view-table m-0">
<tbody>
<tr>
<td>Registered:</td>
<td>{reg.slice(0, 10)}</td>
</tr>
<tr>
<td>Verified:</td>
<td>
<span className="fa fa-check text-primary"></span>
No
</td>
</tr>
<tr>
<td>Role:</td>
<td>{role.charAt(0).toUpperCase() + role.slice(1)}</td>
</tr>
<tr>
<td>Status:</td>
<td>
<span className="badge badge-outline-success">
Active
</span>
</td>
</tr>
</tbody>
</table>
</div>
<hr className="border-light m-0" />
</div>
<div className="card">
<hr className="border-light m-0" />
<div className="card-body">
<h6 className="mt-4 mb-3">Personal Details:</h6>
<table className="table user-view-table m-0">
<tbody>
<tr>
<td>Full Name:</td>
<td>
<div className="col-3">
<input
type="text"
className="form-control"
onChange={onHandleChange("name")}
defaultValue={name}
/>
</div>
</td>
<td></td>
</tr>
<tr>
<td>Email:</td>
<td>{email}</td>
</tr>
<tr>
<td>Phone:</td>
<td>
<div className="col-3">
<input
type="text"
className="form-control"
onChange={onHandleChange("phone")}
defaultValue={phone}
/>
</div>
</td>
</tr>
<tr>
<td>City:</td>
<td>
<div className="col-3">
<input
type="text"
className="form-control"
onChange={onHandleChange("city")}
defaultValue={city}
/>
</div>
</td>
</tr>
<tr>
<td>State:</td>
<td>
<div className="col-3">
<input
type="text"
className="form-control"
onChange={onHandleChange("state")}
defaultValue={state}
/>
</div>
</td>
</tr>
<tr>
<td>Country:</td>
<td>
<div className="col-3">
<input
type="text"
className="form-control"
onChange={onHandleChange("country")}
defaultValue={country}
/>
</div>
</td>
</tr>
</tbody>
</table>
<button onClick={onSubmit} className="btn btn-primary btn-sm">
Submit
</button>
<button
onClick={() => {
setEdit(false);
}}
className="btn btn-primary btn-sm"
>
Cancel
</button>
</div>
</div>
</div>
</>
);
};
// toast to show error
const errorToast = () => {
toast(`${update.error}`, {
position: "top-right",
autoClose: false,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "dark",
});
};
return (
<>
<ToastContainer
position="top-right"
autoClose={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
theme="colored"
/>
{/* {error && (
<>
<Navigate to="/signout" />
</>
)} */}
{edit === true ? (
<>
{profileEdit()} <br />
</>
) : (
<>
{profileMain()} <br />
</>
)}
</>
);
};
export default Profile;
i'm calling two api calls..
get request and everything is working fine.
post request, here i'm unable to send the token to the backend..
i used same method for get request and it was working fine, but when used same method on post request i'm unable to send token..
is there something that i'm missing ?
i have added comment in each line of code.. my english is poor.
sorry and have a great day.
The second argument for Axios.post() is for the POST data and you're setting headers there. Pass an empty object (if you want to have empty POST data) and move your headers (dataToken) to the third argument:
const res = await Axios.post(`${API}/user/profileEdit`, {}, dataToken);
// ^set POST data here
From the documentation:
axios.post(url[, data[, config]])
I have this code in PHP which has path "http://localhost:80/ico/vypsani.php"
$ico = $_POST['ico'];
include_once("core.php");
$sql = "SELECT * FROM ico WHERE ico = '$ico'";
$result = mysqli_query($conn, $sql);
$json_array = array();
while($row = mysqli_fetch_assoc($result)){
$json_array[]=$row;
}
echo json_encode($json_array);
in PHP I am searching row in database with input in React and its working, but I need to ge it into this table
import React,{useState, useEffect} from 'react';
const Data = () =>{
const [item, setItem] = useState([]);
useEffect(()=>{
fetch("http://localhost:80/ico/vypsani.php")
.then(res => res.json())
.then(
(result) => {
setItem(result);
}
)
},[])
return (
<div className="row">
<table class="table table-striped table-dark">
<thead className='thead-dark'>
<tr>
<th scope="col">ID</th>
<th scope="col">IČO</th>
<th scope="col">Název</th>
<th scope="col">Město</th>
<th scope="col">Ulice</th>
<th scope="col">Číslo Domovní</th>
<th scope="col">Číslo Orientační</th>
<th scope="col">Datum uložení</th>
</tr>
</thead>
<tbody>
{
item.map(item=>(
<tr key={item.ID}>
<td>{item.ID}</td>
<td>{item.ico}</td>
<td>{item.nazev}</td>
<td>{item.mesto}</td>
<td>{item.ulice}</td>
<td>{item.cisloDomovni}</td>
<td>{item.cisloOrientacni}</td>
<td>{item.datum}</td>
</tr>
))
}
</tbody>
</table>
</div>
);
}
but it shows the row from database like this and not in react table, I think because of the POST.
How react app looks like
import React from 'react';
import './App.css';
import Data from "./data/data.js";
function App() {
return (
<div className="App">
<form action='http://localhost:80/ico/vypsani.php' method="post">
<div className='form'>
<h1>IČO</h1>
<input name="ico" onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
alert("Zadávat lze pouze čísla")
}
}}
/>
<h1>Název firmy</h1>
<input name="nazev" type="text"></input>
<br></br>
<button type="submit" name='submit' value="vyhledat">Vyhledat</button>
<br></br>
<button type="submit" name='submit' value="odeslat">Odeslat</button>
<br></br>
</div>
<h1>Výpis z Databáze</h1>
<Data/>
</form>
</div>
);
}
export default App;
POSTing form to php page is not the correct way to do this. Please read answer to this question: Send a ReactJS form to a PHP page
To get your code to work, you can remove form in the html and handle the request using fetch only.
Also, change $ico = $_POST['ico']; to $ico = $_GET['ico']; in your php file
import React from 'react';
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
tableData: [],
ico: ''
};
}
handleInput = event => {
this.setState({ ico: event.target.value });
};
logValue = () => {
fetch("http://localhost:80/ico/vypsani.php?ico=" + this.state.ico)
.then(res => res.json())
.then(
(result) => {
this.setState(state => state.tableData = result);
}
)
.catch(err => {
throw err
});
};
render() {
return (
<div className="App">
<div className='form'>
<h1>IČO</h1>
<input name="ico" onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
alert("Zadávat lze pouze čísla")
}
}}
/>
<h1>Název firmy</h1>
<input name="nazev" onChange={this.handleInput} type="text"></input>
<br></br>
<button type="submit" name='submit' onClick={this.logValue} value="vyhledat">Vyhledat</button>
<br></br>
<button type="submit" name='submit' value="odeslat">Odeslat</button>
<br></br>
</div>
<h1>Výpis z Databáze</h1>
<div >
<table class="table table-striped table-dark">
<thead className='thead-dark'>
<tr>
<th scope="col">ID</th>
<th scope="col">IČO</th>
<th scope="col">Název</th>
<th scope="col">Město</th>
<th scope="col">Ulice</th>
<th scope="col">Číslo Domovní</th>
<th scope="col">Číslo Orientační</th>
<th scope="col">Datum uložení</th>
</tr>
</thead>
<tbody>
{
this.state.tableData.map(item => (
<tr key={item.ID}>
<td>{item.ID}</td>
<td>{item.ico}</td>
<td>{item.nazev}</td>
<td>{item.mesto}</td>
<td>{item.ulice}</td>
<td>{item.cisloDomovni}</td>
<td>{item.cisloOrientacni}</td>
<td>{item.datum}</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
);
}
}
export default Test;
Change your useEffect like this
useEffect(()=>{
fetch("http://localhost:80/ico/vypsani.php")
.then(result => {
setItem(result);
console.log(result);
}
)
.catch(error => {
console.log(error)
})
},[])
and table body like this
<tbody>
{
item && item?.map(ele=>(
<tr key={ele.ID}>
<td>{ele.ID}</td>
<td>{ele.ico}</td>
<td>{ele.nazev}</td>
<td>{ele.mesto}</td>
<td>{ele.ulice}</td>
<td>{ele.cisloDomovni}</td>
<td>{ele.cisloOrientacni}</td>
<td>{ele.datum}</td>
</tr>
))
}
</tbody>
So what I have done here is created a table with 5 ByDefault rows for that aI created a array with 5 elements and mapped over it and I got the rows. After that I created an input field in which user can enter the number of extra rows they want, using the "increaseRow" function and the user input I push Elements in the array so that i can get that number of rows and got it as well. But when I Keep the By Default rows as it is and some new rows e.g 5 rows and try to DELETE all 10 rows it creates problem
All I want is the rows should get DELETED.
import { useState } from "react";
import Table from "react-bootstrap/Table";
import './App.css'
const App = () => {
const row1 = [];
const [row, setRow] = useState();
const [NewRow, setNewRow] = useState([1,2,3,4,5]);
const [allRowsAdded, updateAllRows] = useState(0);
const addRow = (e) => {
e.preventDefault();
setRow(e.target.value);
};
const increaseRow = () => {
for (let i = 0; i < parseInt(row); i++) {
row1[i] = allRowsAdded + i;
}
updateAllRows((allRowsAdded) => allRowsAdded + parseInt(row));
setNewRow([...NewRow, ...row1]);
};
const deleteRow = (id) => {
const updatedRows = [...NewRow].filter((rowId) => {
return rowId !== id;
});
setNewRow(updatedRows);
};
return (
<>
<div>
<form>
<input type="text" onChange={addRow} placeholder="Enter Number Of Row's" /><br />
</form>
<button onClick={increaseRow}> Add </button>
</div>
<div className="container">
<form >
<Table striped bordered hover responsive variant="light">
<thead>
<tr>
<th>
{" "}
<h6> No. </h6>{" "}
</th>
<th>
{" "}
<h6> Injection Speed </h6>{" "}
</th>
<th>
{" "}
<h6> Fill Time </h6>{" "}
</th>
<th>
{" "}
<h6> Peak Inj Press </h6>{" "}
</th>
<th>
{" "}
<h6> Viscocity </h6>{" "}
</th>
<th>
{" "}
<h6> Shear Rate </h6>{" "}
</th>
<th>
{" "}
<h6> AbsoluteDropViscocity </h6>{" "}
</th>
<th>
{" "}
<h6> %DropViscocity </h6>{" "}
</th>
<th>
{" "}
<h6> Action </h6>{" "}
</th>
</tr>
</thead>
<tbody className="grid_style">
{NewRow.map((rowId) => {
return (
<tr key={rowId}>
<td> {rowId} </td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<i
className="fa fa-trash viscocity_icons"
onClick={() => deleteRow(rowId)}
>
</i>
</td>
</tr>
);
})}
</tbody>
</Table>
</form>
</div>
</>
);
};
export default App;
https://codesandbox.io/s/silly-allen-iun6b?file=/src/App.js
This is just a logical error (rowId clashes) that you are doing.
const increaseRow = () => {
for(let i=0; i < row; i++){
row1[i] = i;
}
setNewRow([...NewRow, ...row1]);
}
Here when u are assigning value to a row, you are taking index as id for that row. According to which, this is happening with rowId
and on removing a row and filtering based on rowId, for eg: id=1
const deleteRow = (id) => {
const updatedRows = NewRow.filter((rowId) => {
return rowId!== id;
})
setNewRow(updatedRows)
}
2 rows are removed with rowId=1, ie. at serial number 1 and 6.
Solution
You can correct this by adding anything for unique Keys, like uuid. Here I have used an extra state variable const [allRowsAdded, updateAllRows] = useState(0); which stores the total number of rows added from now and add the rowIds next to the addedRows.
const increaseRow = () => {
for (let i = 0; i < parseInt(row); i++) {
row1[i] = allRowsAdded + i;
}
updateAllRows((allRowsAdded) => allRowsAdded + parseInt(row));
setNewRow([...NewRow, ...row1]);
};
Now, rowIds becomes
And there will be no rowId clashes.
Code Link : https://codesandbox.io/s/quiet-snowflake-26v1o?file=/src/App.js
here is by my understanding will work,
const deleteRow = (id) => {
const updatedRows = NewRow.filter((index) => {
return index !== id;
})
setNewRow(updatedRows)
}
change your html code,
<td> <i className="fa fa-trash viscocity_icons" onClick={() => deleteRow(index)}></i> </td>
i dont know about datastructure or json of array,
const deleteRow = (id) => {
const updatedRows = NewRow.filter((e) => {
return e.id !== id;
})
setNewRow(updatedRows)
}
I am doing a call for an API (fake, just for testing), but i recive an error when calling it
This is my code of the call
class Pacientes extends React.Component {
state = {
loading: true,
error: null,
data: undefined,
};
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
this.setState({ loading: true, error: null });
try {
const data = await api.pacientes.list();
this.setState({ loading: false, data: data });
} catch (error) {
this.setState({ loading: false, error: error });
}
};
render() {
if (this.state.loading === true && !this.state.data)
return (
<PageLoading/>
);
if (this.state.error) return (
`Este fue el error ${this.state.error}`
);
return (
<React.Fragment>
<TableHeader elementos={this.state.data} />
<Table pacientes={this.state.data} />
</React.Fragment>
);
}
}
And the console says than the error is on the following line :
this.setState({ loading: false, data: data });
But I think than there is not.
Then of make the call of the api i call a component and give props of the answer of the api(Data), and this is the component:
function useSearchPacientes(pacientes) {
const [query, setQuery] = React.useState('');
const [filteredPacientes, setFilteredPacientes] = React.useState(pacientes);
React.useMemo(() => {
const result = pacientes.filter(paciente => {
return (
`${paciente.firstName} ${paciente.lastName}`
)
.toLowerCase()
.includes(query.toLowerCase());
});
setFilteredPacientes(result);
}, [pacientes, query]);
return { query, setQuery, filteredPacientes };
}
function Table(props) {
const pacientes = props.pacientes;
const { query, setQuery, filteredPacientes } = useSearchPacientes(pacientes);
if (filteredPacientes.length === 0) {
return (
"No se encontraron resultados"
);
return (
<React.Fragment>
<div className="search-container">
<form className="search-input-container">
<input type="text" className="search-input form-control" placeholder="Buscar"
value={query}
onChange={(e) => {
setQuery(e.target.value);
}}
/>
<FontAwesomeIcon icon={faSearch} className="text-muted search-input-icon"/>
</form>
<div className="options">
<select name="" className="form-control" id="">
<option value=""></option>
<option value=""></option>
<option value=""></option>
</select>
</div>
</div>
<br />
<div className="row justify-content-center">
<div className="col-10 table-container border-primary">
<br />
<table className="table rounded table-responsive-md">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nombre</th>
<th scope="col">Apellido</th>
<th scope="col">Twitter</th>
<th scope="col" className="text-center">
Opciones
</th>
</tr>
</thead>
<tbody>
{filteredPacientes.map(paciente => {
return (
<tr key={paciente.id}>
<TableRow paciente={paciente} />
</tr>
);
})}
</tbody>
</table>
</div>
</div>
<br />
</React.Fragment>
);
}
}
So, then of serch this error, i cant found a real solution, but i really think than the error is in the second component, near of the map function to the array.
You have wrongly used closing curly bracket for your if condition
function Table(props) {
const pacientes = props.pacientes;
const { query, setQuery, filteredPacientes } = useSearchPacientes(pacientes);
if (filteredPacientes.length === 0) {
return (
"No se encontraron resultados"
);
} // the closing bracket should be here
return (
<React.Fragment>
<div className="search-container">
<form className="search-input-container">
<input type="text" className="search-input form-control" placeholder="Buscar"
value={query}
onChange={(e) => {
setQuery(e.target.value);
}}
/>
<FontAwesomeIcon icon={faSearch} className="text-muted search-input-icon"/>
</form>
<div className="options">
<select name="" className="form-control" id="">
<option value=""></option>
<option value=""></option>
<option value=""></option>
</select>
</div>
</div>
<br />
<div className="row justify-content-center">
<div className="col-10 table-container border-primary">
<br />
<table className="table rounded table-responsive-md">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nombre</th>
<th scope="col">Apellido</th>
<th scope="col">Twitter</th>
<th scope="col" className="text-center">
Opciones
</th>
</tr>
</thead>
<tbody>
{filteredPacientes.map(paciente => {
return (
<tr key={paciente.id}>
<TableRow paciente={paciente} />
</tr>
);
})}
</tbody>
</table>
</div>
</div>
<br />
</React.Fragment>
);
}
I am using mongoose-paginate-v2 on the backend to paginate the response from my DB. I am trying to setup the front end to move through the data and send a request for the new data as needed. (That part seems to be working). The problem I am having is the DOM seems to freak out after pressing the next / back buttons a few times. VIDEO of problem which is at the end of the 20sec vid: (https://drive.google.com/file/d/1btfeKqXELEMmBnFPpkCbBLY5uhrC1bvE/view?usp=sharing)
What I have tried: I have tried .emtpy, .remove, and now .replace all seem to have the same problem. I have also moved the code around to try and make it unti the prior .then() was complete. Here is the code:
Front End:
<% include ../partials/header%>
<div class="container-fluid pt-3">
<div class='row'>
<div class="col-md-1">
<button class="btn btn-outline-primary sticky-top">Start New Call</button>
</div>
<div class="col-md-11">
<table class="table">
<thead class="sticky-top">
<tr>
<th scope="col">Incident #</th>
<th scope="col">Type</th>
<th scope="col">Location</th>
<th scope="col">Units</th>
<th scope="col">Dispatch</th>
<th scope="col">Clear</th>
<th scope="col">Disposition</th>
<th scope="col">Recall</th>
</tr>
</thead>
<tbody id="callTable">
<tr id="row1"><td></td></tr>
<tr id="row2"><td></td></tr>
<tr id="row3"><td></td></tr>
<tr id="row4"><td></td></tr>
<tr id="row5"><td></td></tr>
<tr id="row6"><td></td></tr>
<tr id="row7"><td></td></tr>
<tr id="row8"><td></td></tr>
<tr id="row9"><td></td></tr>
<tr id="row10"><td></td></tr>
</tbody>
</table>
<div class="row">
<div class="col-3"></div>
<div class="text-center col-2">
<button id="back" class="btn btn-outline-success mr-auto"><i class="fas fa-step-backward"></i><strong>Back</strong></button>
</div>
<div class="justify-content-center d-flex col-2 align-items-center">
<strong>Page <span id="pgnum">##</span> of <span id="totalpgs">##</span></strong>
</div>
<div class="text-center col-2">
<button id="next" class="btn btn-outline-success ml-auto"><strong>Next</strong><i class="fas fa-step-forward"></i></button>
</div>
<div class="text-center col-3"></div>
</div>
</div>
</div>
</div>
<% include ../partials/footer %>
<script>
//Data Management Script
let list=[];
axios.get('/api/cnc/incidents')
.catch(err=>{
console.log(err);
})
.then(data=>{
return list=data;
})
//Setup Function to get data...
async function getPage(page){
axios.get('/api/cnc/incidents/'+page)
.catch(err=>{
console.log(err);
})
.then(response=>{
console.log(response);
calls = response.data.docs;
callNumber = 'Not Assigned';
next = response.data.hasNextPage,
back = response.data.hasPrevPage,
nextPage = response.data.nextPage,
prevPage = response.data.prevPage;
$('#pgnum').text(response.data.page);
$('#totalpgs').text(response.data.totalPages);
if(next === true){
$('#next').removeAttr('disabled');
$('#next').click(function () {
getPage(nextPage);
});
}else{
$('#next').attr('disabled', 'disabled');
}
if(back === true){
$('#back').removeAttr('disabled');
$('#back').click(function () {
getPage(prevPage);
});
}else{
$('#back').attr('disabled', 'disabled');
}
// activities.sort((a, b) => b.date - a.date)
calls.sort((a, b) => (a.times.dispatch > b.times.dispatch) ? -1 : 1)
return calls;
}).then(calls=>{
let i = 1;
calls.forEach(call => {
//Set default callNumber.
callNumber = 'Not Assigned'
//Update to call number from DB.
if(call.incidentNumber){
callNumber = call.incidentNumber;
}
//Change _id to Radio ID.
if(call.units.length > 0){
let assignedUnits = call.units;
let idArray = list.data[0];
const filtered = [];
function compare(assignedUnits,idArray){
assignedUnits.forEach((unit)=>{
idArray.forEach((unitId)=>{
if(unit === unitId._id){
filtered.push(unitId.id);
}
})
})
return filtered;
}
compare(assignedUnits, idArray);
callUnits = filtered.join(', ');
}else{
callUnits = ['None']
}
if(typeof call.disposition !== 'undefined'){
callDisposition = call.disposition.selected;
}else{
callDisposition = '';
}
if(call.times.clear === undefined){
callClear = '';
}else{
callClear = call.times.clear;
}
//Insert Data into DOM. and make TR the link to edit
$('#row'+i).replaceWith('<tr id="row'+i+'" onClick="editRun(\''+call._id+'\')"><th>'+callNumber+'</th><td>'+call.callType+'</td><td>'+call.address.placeName+' '+call.address.streetAddress+'</td><td>'+callUnits+'</td><td>'+call.times.dispatch+'</td><td>'+callClear+'</td><td>'+callDisposition+'</td><td id="recall">'+call.recall.length+' personnel</td></tr>');
i++;
});
})
}
//Get the first page of data...
getPage(1);
function editRun(runId){
window.location.href= '/api/cnc/incident/input/'+runId;
}
//Update Navbar correctly
$('document').ready(function(){
$('.top-nav').removeClass('active').addClass('text-light').removeClass('text-dark');
$('#incidentTab').addClass('active').addClass('text-dark').removeClass('text-light');
});
</script>