Fetch axios response to new window or new url - reactjs

i'm created one dropdown that used for querying the database and show the result as axios response . but right now i can only use it in console.log(res.data) what i want is something like load response in new url or new file.
full react code:
import React from "react";
import axios from 'axios';
class Inference extends React.Component {
constructor(props) {
super(props);
this.state = {
courses: [],
course: "",
model: "",
options: [
{ label: "model1", value: "model1" },
{ label: "model2", value: "model2" },
{ label: "model3", value: "model3" },
],
};
this.handleChangeCourse = this.handleChangeCourse.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange = event => {
this.setState({ model: event.target.value });
};
handleChangeCourse = event => {
this.setState({ course: event.target.value });
};
getUnique(arr, comp) {
const unique = arr
//store the comparison values in array
.map(e => e[comp])
// store the keys of the unique objects
.map((e, i, final) => final.indexOf(e) === i && i)
// eliminate the dead keys & store unique objects
.filter(e => arr[e])
.map(e => arr[e]);
return unique;
}
handleSubmit(event) {
event.preventDefault();
axios.post('http://localhost:5000/getmodell', {
model: this.state.model,
dataset:this.state.course
})
.then((res) => {
// Res.data is the response from your server
console.log(res.data);
});
}
componentDidMount() {
axios.get('http://localhost:5000/files')
.then(response => this.setState({ courses: response.data }));
}
render() {
const uniqueCouse = this.getUnique(this.state.courses, "dataset");
const courses = this.state.courses;
const course = this.state.course;
const options = this.state.options;
const filterDropdown = courses.filter(function(result) {
return result.dataset === course;
});
return (
<div className="container">
<div className="row">
<form onSubmit={this.handleSubmit.bind(this)}>
<div className="col-4"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}>
<label style={{ paddingTop: "5px", marginTop: "40px" }}>
Dataset
<select classname="custom-select"
value={this.state.course}
onChange={this.handleChangeCourse} style={{ paddingTop: "5px", marginTop: "10px" }}
>
{uniqueCouse.map(course => (
<option key={course.id} value={course.dataset}>
{course.dataset}
</option>
))}
</select>
</label>
<div className="col-4">
<button
type="submit"
class="btn"
style={{ marginTop: "" }}
>
ok
</button>
</div>
<div>
{filterDropdown.map(course => (
<div key={course.id} style={{ margin: "10px" }}>
<img src={`${course.path}`} height="80" className="card-img-top img-responsive" alt="img"/>
<br />
</div>
))}
</div>
</div>
<div
className="col-4"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}
>
<label
className=""
style={{ paddingTop: "5px", marginTop: "40px" }}
>
Model
<select
className="custom-select"
name="example"
value={this.state.model}
onChange={this.handleChange}
style={{ paddingTop: "5px", marginTop: "10px" }}
>
<option>--Select--</option>
{options.map((option) => (
<option
value={option.value}
onChange={(e) => this.setState({ model: e.target.value })}
>
{option.label}
</option>
))}
</select>
</label>
</div>
</form>
</div>
</div>
);
}
}
export default Inference;
this code works perfectly fine i can able to see the results in console log. i want to see the results in new url or stores as new json. kindly help me

Related

How can I add the 'All' checkbox in order to select all the other options?

how can I add the All checkboxes that will select all the other checkboxes for each Type of plant and adding a checkbox in front of each Type of plant section. So when I select one option Plant 1.1 then my checkbox for Type of plant #1 is filled, and if option is filled then the checkbox for Type of plant is not filled.
export default function Category({
_id_type,
name_type,
plants,
changeSelection
}) {
const [toggleState, setToggleState] = useState(false);
return (
<div key={_id_type}>
<div
style={{
cursor: "pointer",
userSelect: "none",
display: "flex",
margin: "2px",
backgroundColor: "lightgray"
}}
onClick={() => setToggleState((prev) => !prev)}
>
<div>{name_type}</div>
<div
style={{
backgroundColor: "blue",
color: "white",
padding: "0px 10px",
marginLeft: "auto"
}}
>
{plants.filter(({ selected }) => selected).length}
</div>
</div>
<div style={{ marginLeft: "10px" }}>
{toggleState &&
plants.map(({ name, _id, selected }) => (
<div key={_id}>
<input
key={_id}
type="checkbox"
value={name}
checked={selected}
onChange={(e) => changeSelection(_id_type, _id, e.target.value)}
/>
{name}
</div>
))}
</div>
</div>
);
}
Here a picture (what I have/ what I want) :
Here is my code
add new toogle inside category.jsx
{toggleState && plants.length > 1 ? (
<div>
<input
type="checkbox"
value={"all"}
checked={allSelected}
onChange={(e) => {
setAllSelected((v) => {
changeSelection(_id_type, "all", e.target.value, !v);
return !v;
});
}}
/>
All
</div>
) : (
""
)}
edit change selection function:
const changeSelection = (catId, itemId, value, allSelected) => {
setSelectionMenu((prevSelectionMenu) =>
prevSelectionMenu.map((item) => {
if (item._id_type === catId) {
return {
...item,
plants: item.plants.map((plant) => {
if (plant._id === itemId) {
return { ...plant, selected: !plant.selected };
} else if (itemId === "all") {
return { ...plant, selected: allSelected };
}
return plant;
})
};
}
return item;
})
);
};
here the forked code:
https://codesandbox.io/embed/plants-forked-qdmz2h?fontsize=14&hidenavigation=1&theme=dark

Validation of textbox message:- (fill the value)

I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
import React, { useState } from 'react'
import './AddRecipes.css'
import axios from 'axios'
function AddRecipes() {
const [state, setstate] = useState({
label: '',
source: '',
dietlabels: [],
healthlabels: [],
cuisineType: [],
ingredients: [],
mealType: [],
makingDescription: '',
recipeImage: null
})
state={
dietlabels= " This is empty fild",
healthlabels= "",
cuisineType ="",
ingredients= "",
mealType= ""
};
const onFormSubmit = async (e) => {
e.preventDefault()
console.log(state.ingredients)
try {
const fd = new FormData()
fd.append('recipeImage', state.recipeImage, state.recipeImage.name)
fd.append('label', state.label)
fd.append('source', state.source)
fd.append('dietlabels', JSON.stringify(state.dietlabels))
fd.append('healthlabels', JSON.stringify(state.healthlabels))
fd.append('ingredients', JSON.stringify(state.ingredients))
fd.append('cuisineType', JSON.stringify(state.cuisineType))
fd.append('mealType', JSON.stringify(state.mealType))
fd.append('makingDescription', state.makingDescription)
// console.log(fd)
const { data: response } = await axios.post(
'http://localhost:8000/recipe',
fd
)
console.log('api response' + response)
} catch (error) {
console.log(error)
}
}
const [arrayState, arraySetSate] = useState({
dietlabels: '',
healthlabels: '',
cuisineType: '',
ingredients: { text: '', weight: '' },
mealType: ''
})
const subIngredientStatePush = (event) => {
let replica = { ...arrayState }
replica.ingredients[event.target.name] = event.target.value
arraySetSate(replica)
}
//string type field data handling
const stringTypeFieldDataHandler = (event) => {
let replicateState = { ...state }
replicateState[event.target.name] = event.target.value
setstate(replicateState)
}
//image file handling
const imageUploadFileHandler = (event) => {
let replicateState = { ...state }
replicateState['recipeImage'] = event.target.files[0]
setstate(replicateState)
}
//array elements data handling
const arrayElementSeparateStateHandler = (event) => {
let repilica = { ...arrayState }
repilica[event.target.name] = event.target.value
arraySetSate(repilica)
}
const addDietLabels = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.dietlabels.push(arrayState.dietlabels)
setstate(replica)
arrayreplica.dietlabels = ''
arraySetSate(arrayreplica)
}
const newlable =()=>{
}
const addHealthLables = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.healthlabels.push(arrayState.healthlabels)
setstate(replica)
arrayreplica.healthlabels = ''
arraySetSate(arrayreplica)
}
const addcuisineType = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.cuisineType.push(arrayState.cuisineType)
setstate(replica)
arrayreplica.cuisineType = ''
arraySetSate(arrayreplica)
}
const addmealType = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.mealType.push(arrayState.mealType)
setstate(replica)
arrayreplica.mealType = ''
arraySetSate(arrayreplica)
}
const AddingredientsClick = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
let ingredientObj = {
text: arrayState.ingredients.text,
weight: arrayState.ingredients.weight
}
replica.ingredients.push(ingredientObj)
setstate(replica)
arrayreplica.ingredients = { text: '', weight: '' }
arraySetSate(arrayreplica)
}
return (
<div className="recipeForm container">
<form
style={{
display: 'flex',
flexDirection: 'column',
width: '70%',
alignItems: 'center'
}}
>
<label className="addrecipe-labels" htmlFor="label">
Enter Recipe Name
</label>
<input
type="text"
id="label"
name="label"
placeholder="recipe name"
className="inputs"
value={state.label}
onChange={stringTypeFieldDataHandler}
/>
<br />
<label className="addrecipe-labels" htmlFor="source">
Recipe Source
</label>
<input
type="text"
id="source"
name="source"
placeholder="enter source"
value={state.source}
onChange={stringTypeFieldDataHandler}
className="inputs"
/>
{/* <label className="addrecipe-labels" htmlFor="url">
URL
</label>
<input
type="text"
id="url"
name="url"
placeholder="paste url"
className="inputs"
/> */}
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="dietlabels">
diet labels
</label>
<input
type="text"
id="dietlabels"
name="dietlabels"
onChange={arrayElementSeparateStateHandler}
onChange={newlable}
value={arrayState.dietlabels}
placeholder="type labels"
className="inputs"
/>
<div>{this.state.nameError}</div>
<button
style={{ width: '40px' }}
type="button"
onClick={addDietLabels}
>
Add
</button>
<p>{String(state.dietlabels)}</p>
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="healthlabels">
Health labels
</label>
<input
type="text"
value={arrayState.healthlabels}
onChange={arrayElementSeparateStateHandler}
id="healthlabels"
name="healthlabels"
placeholder="health lables"
className="inputs"
/>
<button
style={{ width: '40px' }}
type="button"
onClick={addHealthLables}
>
Add
</button>
{String(state.healthlabels)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="cuisineType">
cuisine type
</label>
<input
type="text"
id="cuisineType"
value={arrayState.cuisineType}
onChange={arrayElementSeparateStateHandler}
name="cuisineType"
placeholder="add cautions"
className="inputs"
/>
<button
style={{ width: '40px' }}
type="button"
onClick={addcuisineType}
>
Add
</button>
{String(state.cuisineType)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="mealtype">
meal type
</label>
<input
type="text"
id="mealtype"
name="mealType"
value={arrayState.mealType}
onChange={arrayElementSeparateStateHandler}
placeholder="add cautions"
className="inputs"
/>
<button style={{ width: '40px' }} type="button" onClick={addmealType}>
Add
</button>
{String(state.mealType)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="ingredients">
ingredients
</label>
<input
type="text"
id="ingredients"
name="text"
value={arrayState.ingredients.text}
placeholder="ingredient"
className="inputs"
onChange={subIngredientStatePush}
style={{ margin: '0 5px' }}
/>
<input
type="text"
id="quantity"
name="weight"
value={arrayState.ingredients.weight}
onChange={subIngredientStatePush}
placeholder="quantity"
className="inputs"
/>
<button
style={{ width: '50px', marginLeft: '7px' }}
type="button"
onClick={AddingredientsClick}
>
Add
</button>
{JSON.stringify(state.ingredients)}
</div>
{/*
<label className="addrecipe-labels" htmlFor="country">
Country
</label>
<select id="country" name="country" className="inputs">
<option value="australia">Australia</option>
<option value="canada">Canada</option>
<option value="usa">USA</option>
</select> */}
<label className="addrecipe-labels" htmlFor="recipe-description">
Recipe description
</label>
<textarea
id="recipe-description"
name="makingDescription"
value={state.makingDescription}
onChange={stringTypeFieldDataHandler}
placeholder="Write something.."
style={{ height: '200px' }}
className="inputs"
></textarea>
<div style={{ margin: '15px 0' }}>
<label className="addrecipe-labels" htmlFor="recipeImage">
Add recipe image
</label>
<input
type="file"
name="recipeImage"
onChange={imageUploadFileHandler}
id="recipeImage"
/>
</div>
<input
type="submit"
value="Submit"
className="inputs submit"
onClick={onFormSubmit}
/>
</form>
</div>
)
}
export default AddRecipes
You have a couple of mistakes within your code but I'll focus on your question.
To validate, you add the validation logic either to the onChange or onSubmit callback.
onChange callback example
const subIngredientStatePush = ({ target: { name, value }}) => {
// validate
if (name === "text" && value.length > 10) {
setError((errors) => ({ ...errors, [name]: "too long" });
}
//... etc
// update state
const replica = { ...arrayState };
replica.ingredients = { ...replica.ingredients }; // need to copy this state as well
replica.ingredients[name] = value
arraySetSate(replica)
}

Create dynamic json based on user input

I have two dropdowns and a couple of images on it what I want is when the user selects the dropdowns and selects image I want to create the JSON format like below:
[data: {
dropdown1:'user input',
dropdown2:'user input',
image url:'url'
}]
my react code:
import React from "react";
import axios from 'axios'
import '../Login.css'
export default class Inference extends React.Component {
constructor(props) {
super(props);
this.state = {
courses: [],
course: "",
inferenceout: [],
model: "",
isLoading: false,
options: [
{ label: "resnet-50torch", value: "resnet-50torch" },
{ label: "densenet_onnx", value: "densenet_onnx" },
{ label: "inception_graphdef", value: "inception_graphdef" },
],
};
this.handleChange = this.handleChange.bind(this);
this.handleChangeCourse = this.handleChangeCourse.bind(this);
this.click = this.click.bind(this);
}
handleChange(e) {
console.log("Model Selected!!");
this.setState({ model: e.target.value });
}
handleChangeCourse = (event) => {
this.setState({ course: event.target.value });
};
getUnique(arr, comp) {
const unique = arr
//store the comparison values in array
.map((e) => e[comp])
// store the keys of the unique objects
.map((e, i, final) => final.indexOf(e) === i && i)
// eliminate the dead keys & store unique objects
.filter((e) => arr[e])
.map((e) => arr[e]);
return unique;
}
click() {
this.setState({ isLoading: true });
axios
.get(
`http://localhost:5000/model-list`
)
.then((res) => {
this.setState({
inferenceout: res.data , isLoading: false,
})
let newWin = window.open("about:blank", "res.data", "width=400,height=400");
newWin.document.write(JSON.stringify(res.data))
localStorage.setItem("apiData", JSON.stringify(res.data));
var data = JSON.parse(localStorage.getItem("apiData"));
console.log(data)
})
}
handleSubmit(event) {
event.preventDefault();
axios.post('http://localhost:5000/getmodel', {
model: this.state.model,
dataset:this.state.course
})
.then((res) => {
// Res.data is the response from your server
localStorage.setItem("apiData1", JSON.stringify(res.data));
});
var data = JSON.parse(localStorage.getItem("apiData1"));
console.log(data)
}
componentDidMount() {
axios
.get(`http://localhost:5000/files`)
.then((response) =>
this.setState(
{
courses: response.data
},
)
)
.catch((err) => console.log(err))
}
render() {
const uniqueCouse = this.getUnique(this.state.courses, "dataset");
const { courses, course, options } = this.state;
const filterDropdown = courses.filter(function (result) {
return result.dataset === course;
});
return (
<div className="container">
<div className="row">
<div
className="col-6"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}
>
<label
className=""
style={{ paddingTop: "5px", marginTop: "40px" }}
>
Dataset
<form onSubmit={this.handleSubmit.bind(this)}>
<select
className="custom-select"
value={this.state.course}
onChange={this.handleChangeCourse}
style={{ paddingTop: "5px", marginTop: "10px" }}
>
<option>--Select--</option>
{uniqueCouse.map((course) => (
<option key={course.id} value={course.dataset}
onChange={(e) => this.setState({ dataset: e.target.value })}>
{course.dataset}
</option>
))}
</select>
<button
type="submit"
class="btn"
style={{ marginTop: "" }}
>
ok
</button>
</form>
</label>
</div>
<div
className="col-6"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}
>
<label
className=""
style={{ paddingTop: "5px", marginTop: "40px" }}
>
Model
<form onSubmit={this.handleSubmit.bind(this)}>
<select
className="custom-select"
name="example"
value={this.state.model}
onChange={this.handleChange}
style={{ paddingTop: "5px", marginTop: "10px" }}
>
<option>--Select--</option>
{options.map((option) => (
<option
value={option.value}
onChange={(e) => this.setState({ model: e.target.value })}
>
{option.label}
</option>
))}
</select>
<button
type="submit"
class="btn"
style={{ marginTop: "" }}
>
ok
</button>
</form>
</label>
</div>
{filterDropdown.map((course) => (
<div className="col-2">
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1" className="labell">
<img
key={course.id}
src={`${course.path}`}
height="80"
className="card-img-top img-responsive"
alt="img"
/>
</label>
</div>
))}
<button
type="submit" onClick={this.click} disabled={this.state.isLoading}
class="btn btn-success"
style={{ marginLeft:"45%" ,marginBottom:"10px"}}
>
Inference
</button>
<button
type="submit"
class="btn btn-primary"
style={{ marginLeft:"45%"}} onClick={()=> window.open("/visual", "data","width=400,height=400")}
>
Get Output
</button>
</div>
</div>
);
}
}
the dropdown data are coming from nodejs and images from nodejs also. i want to get the user input as a JSON. i couldn't able to do that thats why i'm asking here kindly help me
please guide me on how to do that

Why my props are undefined when sending to components?

I have a table in my project and I have an edit / view / add page that I can access from this table. My goal is to send the clicked data to the other component without any problem, but no matter how hard I try, I get an undefined error and the project is broken. I would be glad if you could help.
I am sharing my codes from parent to child component
Table page.
import React, { useState, useEffect, useCallback, useMemo } from "react";
import ManagementTable from '../components/ManagementTable'
import {
getApps,
updateStopRisk,
countLiveCountry,
updateAppShow,
deleteApp,
} from "../api/apiCalls";
import VisibilityIcon from "#material-ui/icons/Visibility";
import DeleteIcon from "#material-ui/icons/Delete";
import EditIcon from "#material-ui/icons/Edit";
import Switch from "#material-ui/core/Switch";
import DeleteModal from "../components/DeleteModal";
import { Link } from "react-router-dom";
const Management = () => {
const [apps, setApps] = useState([]);
const [modalVisible, setModalVisible] = useState(false);
const [currentApp, setCurrentApp] = useState("");
const [appID, setAppID] = useState(0);
const fetchData = useCallback(async () => {
const { data: appsResponse } = await getApps();
const countLiveCountries = await fetchLiveCountriesForApps(appsResponse);
setApps(
appsResponse.map((app, idx) => ({
...app,
countLiveCountry: countLiveCountries[idx],
}))
);
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
const fetchLiveCountriesForApps = async (appwLive) => {
const countLiveCountries = await Promise.all(
appwLive.map((app) => countLiveCountry(app.appID))
);
return countLiveCountries.map(({ data: liveCountries }) => liveCountries);
};
const removeApp = async () => {
await deleteApp(appID);
setModalVisible(false);
fetchData();
};
const onClickCancel = () => {
setModalVisible(false);
};
const columns = useMemo(() => [
{
Header: "Application Name",
accessor: "app_name",
},
{
Header: "Business Area",
accessor: "businessarea.businessarea_name",
},
{
Header: "Live Plants",
accessor: "countLiveCountry",
},
{
Header: "Line Stop Risk",
accessor: "app_stoprisk",
Cell: ({ row: { original } }) => {
const changeCheck = async (id) => {
await updateStopRisk(id);
fetchData();
};
return (
<input
checked={original.app_stoprisk}
onClick={() => {
changeCheck(original.appID);
}}
id="appStopRisk"
type="checkbox"
style={{ width: 18, height: 18, marginTop: 5 }}
/>
)
},
sortType: (a, b, id) => {
if (a.original[id] > b.original[id]) return -1;
if (b.original[id] > a.original[id]) return 1;
},
},
{
Header: "Actions",
Cell: ({ row: { original } }) => {
const changeTrack = async (id) => {
await updateAppShow(id);
fetchData();
};
return (
<>
<Link
className="btn btn-manage-link btn-sm col-2"
to={{
pathname: `/management/${original.app_name}`,
mode: "view",
id: original.appID
}}
>
<VisibilityIcon></VisibilityIcon>
</Link>
<Link
to={{
pathname: `/management/${original.app_name}`,
mode: "edit",
id: original.appID
}}
className="btn btn-manage-link btn-sm col-2"
>
<EditIcon></EditIcon>
</Link>
<button
onClick={() => {
setModalVisible(true);
setCurrentApp(original.app_name);
setAppID(original.appID);
}}
className="btn btn-manage-link btn-sm col-3"
>
<DeleteIcon></DeleteIcon>
</button>
<Switch
onClick={() => changeTrack(original.appID)}
checked={original.app_show}
className="col-3"
></Switch>
</>
)
},
},
],
[fetchData]
);
return (
<div className="container">
<h2 style={{ float: "left", font: "bold" }}>Management</h2>
<div style={{ float: "right" }}>
<Link className="btn btn-danger btn-sm" to={{ pathname: `/management/add`, mode: "add" }}>
Add New App
</Link>
<Link className="btn btn-danger btn-sm ml-3" exact to="/management/plants">
Plant Management
</Link>
</div>
<ManagementTable columns={columns} data={apps} />
<DeleteModal
message={<strong>{currentApp}</strong>}
variety="app"
onClickCancel={onClickCancel}
onClickOk={removeApp}
visible={modalVisible}
/>
</div>
);
};
export default Management;
The page where I transfer the props.
import React, { useState, useEffect } from "react";
import Accordion from "../components/Accordion";
import Details from '../components/Details'
import {
getByIdApps,
} from "../api/apiCalls";
const ApplicationManagement = (props) => {
const [appById, setAppById] = useState([]);
const { id } = props.location;
const [selectOption, setSelectOption] = useState('add')
useEffect(() => {
getData();
getMode();
}, [])
const getData = async () => {
console.log(props.location.id)
if (props.location.id) {
await getByIdApps(props.location.id).then((response) => setAppById(response.data))
console.log(appById)
console.log(props)
}
else {
setSelectOption('add')
}
}
const getMode = () => props.location.mode ? setSelectOption(props.location.mode) : setSelectOption('add')
const handleOptionChange = (event) => {
console.log(event.target.value)
setSelectOption(event.target.value)
}
return (
<>
<div style={{ margin: 20 }}>
<h1>
{appById.app_shortcode} - {appById.app_fullname}
</h1>
<div className="float-right mb-auto">
<label><input type="radio" value="view" checked={selectOption === 'view'} onChange={handleOptionChange} />View</label>
<label> <input type="radio" value="add" checked={selectOption === 'add'} onChange={handleOptionChange} />Add</label>
<label> <input type="radio" value="edit" checked={selectOption === 'edit'} onChange={handleOptionChange} />Edit</label>
</div>
<br></br>
<div style={{ marginLeft: 50, marginRight: 50 }} >
<Accordion
title={
<div style={{ width: 1350 }}>
<h3>Details</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}
content={
<Details appID={id} data = {appById}></Details>
}
/>
<Accordion title={
<div style={{ width: 1350 }}>
<h3>Links</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}></Accordion>
<Accordion title={
<div style={{ width: 1350 }}>
<h3>Factory Management</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}></Accordion>
<Accordion title={
<div style={{ width: 1350 }}>
<h3>Issues Management</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}></Accordion>
<Accordion title={
<div style={{ width: 1350 }}>
<h3>Middleware Management</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}></Accordion>
</div>)
{selectOption === 'add' ? (
<div>
Add Mode
</div>
) : selectOption === 'view' ? (<div>View Mode</div>) : (<div>eidt</div>)}
</div>
</>
);
};
export default ApplicationManagement;
and the section where the details are kept on the ApplicationManagement page (My code is quite long, I just share the problem part.)
import React, { useState, useEffect } from 'react'
import axios from "axios";
import {
getResponsibleTeams,
getBusinessAreas
} from '../api/apiCalls'
const Details = (props) => {
const [rTeams, setrTeams] = useState([]);
const [bAreas, setbAreas] = useState([]);
const { data } = props;
useEffect(() => {
async function fetchData() {
const getrTeams = await getResponsibleTeams();
const getbAreas = await getBusinessAreas();
axios.all([getrTeams, getbAreas]).then(
axios.spread((...allData) => {
const allrTeams = allData[0].data;
const allbAreas = allData[1].data;
setrTeams(allrTeams);
setbAreas(allbAreas);
})
);
}
fetchData();
}, []);
return (
<div>
<div
style={{
float: "left",
width: 1350,
height: 340,
}}
>
<div className="form-group">
<label style={{ float: "left" }} htmlFor="appFullName">
Frontend:{" "}
</label>
<input
id="appFullName"
type="text"
class="form-control"
placeholder="dsfdsdsf"
value={data.frontend.frontend_name} // error here
//onChange={handleInputChange}
name="appShortCode"
style={{ width: 400, marginLeft: 150 }}
/>
</div>
</div>
</div>
)
}
export default Details;
Later I realized that using asynchronous functions caused some problems. I came up with a solution to this and the problem was solved.
Error Code Here :
<Accordion
title={
<div style={{ width: 1350 }}>
<h3>Details</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}
content={
<Details appID={id} data = {appById}></Details>
}
/>
and the solution to the problem
{appById &&
<Accordion
title={
<div style={{ width: 1350 }}>
<h3>Details</h3>
<hr style={{ backgroundColor: "#aaa" }}></hr>
</div>
}
content={
<Details appID={id} data = {appById}></Details>
}
/>}

reactjs ref only works for last element in array

I am having a parent component and a child component. I want to call a function from my child in my parent component. I am using ref and it works fine, but just for my last element in my array...
Parent:
onClick = () => {
this.child.handleClose(); // do stuff
};
var items = [];
tracks.filter(searchingFor(term)).map(function (title, i) {
items.push(
<div>
<ItemViewAll
onRef={(ref) => (this.child = ref)}
triggerOpen={this.handleOpenParent.bind(this)}
triggerClose={this.handleCloseParent.bind(this)}
key={title.id}
title={title.title}
/>
</div>
);
}, this);
ItemViewAll is imported from my Child component, where the needed functions are located.
Child:
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
handleClose = () => {
this.setState({ open: false });
this.props.triggerClose();
}
It seems like that the ref works only for the last element in my items[]...
Do you have any suggestions on how to make it work for every element in my array?
Here is my full Parent Compoenent, could be heldpful. Still have no clue how to set the ref...
Parent (complete):
const { scaleDown } = transitions;
function searchingFor(term) {
return function (x) {
return (
x.title.toLowerCase().includes(term.toLowerCase()) ||
x.body.toLowerCase().includes(term.toLowerCase())
);
};
}
class ViewAll extends React.Component {
constructor(props) {
super(props);
this.state = {
term: "",
mounted: false,
tracks: [],
hasMoreItems: true,
};
this.searchHandler = this.searchHandler.bind(this);
this.focus = this.focus.bind(this);
}
loadContent() {
var requestUrl = this.props.url;
fetch(requestUrl)
.then((response) => {
return response.json();
})
.then((tracks) => {
this.setState({ tracks: this.state.tracks.concat(tracks) });
})
.catch((err) => {
console.log("There has been an error");
});
}
componentDidMount() {
var requestUrl = this.props.url;
fetch(requestUrl)
.then((response) => {
return response.json();
})
.then((data) => {
this.setState({ tracks: data });
})
.catch((err) => {
console.log("There has been an error");
});
window.scrollTo(0, 0);
this.focus();
}
handleOpenParent() {
this.setState({ show: true });
}
handleCloseParent() {
this.setState({ show: false });
}
searchHandler(event) {
this.setState({ term: event.target.value });
}
focus() {
this.textInput.focus();
}
onClick = () => {
this.child.handleClose(); // do stuff
};
render() {
const { term, data, tracks } = this.state;
const loader = <div className="loader"></div>;
var items = [];
tracks.filter(searchingFor(term)).map(function (title, i) {
items.push(
<div>
<MuiThemeProvider>
<Paper
style={{
borderRadius: "2em",
background:
"linear-gradient(to right, #82f2da 30%, white 100%)",
}}
zDepth={1}
>
<ItemViewAll
onRef={(ref) => (this.child = ref)}
triggerOpen={this.handleOpenParent.bind(this)}
triggerClose={this.handleCloseParent.bind(this)}
key={title.id}
title={title.title}
score={title.vote_average}
overview={title.body}
backdrop={title.image}
description={title.description}
messenger={title.messenger}
twitter={title.twitter}
discord={title.discord}
slack={title.slack}
kik={title.kik}
telegram={title.telegram}
/>
</Paper>
</MuiThemeProvider>
</div>
);
}, this);
return (
<div>
<header className="Header">
{this.state.show && (
<div
style={{ height: 50, width: 50, background: "red" }}
onClick={this.onClick}
></div>
)}
</header>
<div>
<Media query="(max-width: 599px)">
{(matches) =>
matches ? (
<div style={{ marginTop: 100 }}>
<div
style={{
width: "90%",
marginLeft: "auto",
marginRight: "auto",
marginBottom: 50,
}}
>
<MuiThemeProvider>
<TextField
hintText="Welcher Bot darf es sein?"
type="Text"
onChange={this.searchHandler}
value={term}
fullWidth={true}
underlineFocusStyle={{
borderColor: "#82f2da",
borderWidth: 3,
}}
underlineStyle={{
borderColor: "#82f2da",
borderWidth: 1.5,
top: "40px",
}}
hintStyle={{ fontSize: 30, fontFamily: "Anton" }}
inputStyle={{ fontSize: 30, fontFamily: "Anton" }}
ref={(input) => {
this.textInput = input;
}}
style={{ caretColor: "#82f2da" }}
/>
</MuiThemeProvider>
</div>
</div>
) : (
<div style={{ marginTop: 130 }}>
<div
style={{
width: "80%",
marginLeft: "auto",
marginRight: "auto",
marginBottom: 70,
}}
>
<MuiThemeProvider>
<TextField
hintText="Welcher Bot darf es sein?"
type="Text"
onChange={this.searchHandler}
value={term}
fullWidth={true}
underlineFocusStyle={{
borderColor: "#82f2da",
borderWidth: 3,
}}
underlineStyle={{
borderColor: "#82f2da",
borderWidth: 1.5,
top: "50px",
}}
hintStyle={{ fontSize: 40, fontFamily: "Anton" }}
inputStyle={{ fontSize: 40, fontFamily: "Anton" }}
ref={(input) => {
this.textInput = input;
}}
style={{ caretColor: "#82f2da" }}
/>
</MuiThemeProvider>
</div>
</div>
)
}
</Media>
<Media query="(max-width: 599px)">
{(matches) =>
matches ? (
<InfiniteScroll
pageStart={1}
loadMore={this.loadContent.bind(this)}
hasMore={this.state.hasMoreItems}
loader={loader}
initialLoad={false}
>
<StackGrid
columnWidth={180}
gutterHeight={10}
gutterWidth={10}
duration={1500}
monitorImagesLoaded={true}
easing={easings.quadInOut}
appear={scaleDown.appear}
appeared={scaleDown.appeared}
enter={scaleDown.enter}
entered={scaleDown.entered}
leaved={scaleDown.leaved}
>
{items}
</StackGrid>
</InfiniteScroll>
) : (
<InfiniteScroll
pageStart={10}
loadMore={this.loadContent.bind(this)}
hasMore={this.state.hasMoreItems}
loader={loader}
initialLoad={true}
>
<StackGrid
columnWidth={180}
gutterHeight={80}
gutterWidth={80}
duration={1500}
monitorImagesLoaded={true}
easing={easings.quadInOut}
appear={scaleDown.appear}
appeared={scaleDown.appeared}
enter={scaleDown.enter}
entered={scaleDown.entered}
leaved={scaleDown.leaved}
>
{items}
</StackGrid>
</InfiniteScroll>
)
}
</Media>
</div>
</div>
);
}
}
export default ViewAll;
The onClick function schould be called when clicked on the div in my header. But for all elements in my array and not just for the last one.... The onClick function calls again the handleClose() in my Child.
I believe the reason you always get the last element instance, it is because you are iterating an array and for every item, you render a new and overwrite the this.child variable with a new reference of .
But even though, you should not create a ref for each item of element. If you want to get the onClick event, you have to implement this event on the component . If the component is from a third party library, check the documentation to see how to handle events. Usually, it is with onClick event.
hard to say for sure without seeing more of parent component code (i think you may have cut something from that accidentally), so it's just a guess, but you are probably overwriting your ref while mapping over array, hence it's working only for last element. you can find some solutions for that here.

Resources