I am having Uncaught TypeError: this.state.salaryDetails.map is not a function error while using map in react js. What may be the solution for this issue? Following below is the code:
import React, { Component } from 'react';
import httpBrowsing from './../../../utils/httpBrowsing';
import { NativeSelect, FormControl } from '#material-ui/core'
export class Salary extends Component {
constructor() {
super();
this.state = {
salaryDetails: '',
data: {
employeeName: '',
year: '',
month: ''
}
}
}
handleChange = (e) => {
const { name, value } = e.target;
this.setState((pre) => ({
data: {
...pre.data,
[name]: value,
employeeName: this.state.salaryDetails.filter((item) => item[name] === value)
}
}))
}
componentDidMount() {
httpBrowsing.get('/addemployee', true)
.then((data) => {
this.setState({
salaryDetails: data.data,
})
})
.catch(err => {
console.log("error", this.state);
debugger;
})
}
render() {
console.log("what is this >>", this.state);
console.log("finally>>", this.state);
const { salaryDetails } = this.state;
let Employ = this.state.salaryDetails.map((item, id) => <option key={id} value=
{item.name}>{item.name}</option>)
return (
<div>
<div className="container">
<div className="row">
<div className="col-md-6">
<label htmlFor="month">Month:</label>
<FormControl>
<NativeSelect defaultValue="" name="month" onChange=
{this.handleChange}>
<option >Choose</option>
<option value="january">January</option>
<option value="february">February</option>
<option value="march">March</option>
<option value="april">April</option>
<option value="may">May</option>
<option value="june">June</option>
<option value="july">July</option>
<option value="august">August</option>
<option value="september">September</option>
<option value="october">October</option>
<option value="november">November</option>
<option value="december">December</option>
</NativeSelect>
</FormControl><br />
</div>
<div className="col-md-6">
<label htmlFor="year">Current Year:</label>
<FormControl>
<NativeSelect defaultValue="" name="Year" onChange=
{this.handleChange}>
<option >Choose</option>
<option value="2020">2020</option>
<option value="2019">2019</option>
<option value="2018">2018</option>
<option value="2017">2017</option>
<option value="2016">2016</option>
<option value="2015">2015</option>
</NativeSelect>
</FormControl><br />
</div>
</div>
<div className="col-md-6">
<label htmlFor="Select Employee">Select Employee:</label>
<FormControl>
<NativeSelect defaultValue="" name="name" onChange=
{this.handleChange}>
<option >Choose</option>
{Employ}
</NativeSelect>
</FormControl><br />
</div>
</div>
</div >
)
}
}
I tried to use option from database using native select of material UI,but error is shown.what may be the issue ?what may be the solution for the problem?How can i solve the issue?
Please provide me a solution.
Looking at the constructor within the component, the salaryDetails state is initialised as an empty string, ''.
Array.map() can only be used on arrays. THerefore, you should be initialising your salaryDetails state as an empty array.
this.state = {
salaryDetails: [],
data: {
employeeName: '',
year: '',
month: '',
},
}
Related
My question is that I am doing data filtering using formik and I change the query of the URL when I submit the form and it worked. now the problem is that when I open a new tab in the browser and paste the URL with the queries in it the form value "the select element value" does not change according to the URL queries. I tried to debug it but I failed.
import Head from "next/head";
import { Formik, Field, Form } from "formik";
import router, { useRouter } from "next/router";
import { useState, useEffect } from "react";
export default function Home() {
const { query } = useRouter();
const [initialValues, setInitialValues] = useState({
categories: query.categories || "all-categories",
color: query.color || "all-color",
size: query.size || "all-size",
});
return (
<div>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
</Head>
<Formik
initialValues={initialValues}
onSubmit={(values) => {
router.push({ pathname: "/", query: values }, undefined, {
shallow: true,
});
}}
>
<Form>
<Field label="categories" as="select" name="categories">
<option value="all-categories">get all</option>
<option value="electronics">electronics</option>
<option value="jewelery">jewelery</option>
<option value="men-clothing">men's clothing</option>
<option value="women-clothing">women's clothing</option>
</Field>
<Field label="categories" as="select" name="color">
<option value="all color">all color</option>
<option value="red">Red</option>
<option value="black">Black</option>
<option value="white">White</option>
</Field>
<Field label="size" as="select" name="size">
<option value="all-size">all size</option>
<option value="s">S</option>
<option value="m">M</option>
<option value="l">L</option>
<option value="xl">XL</option>
</Field>
<button type="submit">Submit</button>
</Form>
);
</Formik>
</div>
);
}
I'm working on react and I have several drop-down and text fields where I want to clear/reset selected values from the select options and from the text field when I click the clear button. I've tried some logic, but it doesn't work. can someone help me? I created a function called "handleReset" but it does nothing and doesn't show an error.
Here is my code:
import React, { useState, useEffect } from "react";
import {
Button,
Container,
} from "react-bootstrap";
import { CarAction } from "../../Store/Actions/CarAction";
import { useDispatch, useSelector } from "react-redux";
const CarRequests = () => {
const dispatch = useDispatch();
const getCarMake = useSelector((state) => state.CarReducer.car);
const getCarMileage = useSelector((state) => state.CarReducer.mileage);
const getCarTrim = useSelector((state) => state.CarReducer.trim);
let [value, setValue] = useState()
let handleChange = (e) => {
setValue(e.target.value)
}
const handleReset = (e) => {
setValue(e.target.value = "");
}
useEffect(() => {
dispatch(CarAction.CarMake());
dispatch(CarAction.CarMileage());
dispatch(CarAction.CarTrim());
}, [dispatch]);
return (
<div className="flex-row align-items-center section">
<h3>
Filters
<i className="fa fa-cog icon float-right"></i>
</h3>
<Container className="box-shadow p-4">
<div className="form-row">
<div className="form-group col-lg-3">
<label>Make:</label>
<select className="custom-select" onChange={handleChange}>
<option value=''>Please select...</option>
{getCarMake.map((data, key) => <option value={data.value} key={key}>{data.name}</option>)}
</select>
</div>
<div className="form-group col-md-3">
<label>Model:</label>
<select className="custom-select">
<option value=''>Please select...</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
<div className="form-group col-md-3">
<label>Year:</label>
<select className="custom-select">
<option value=''>Please select...</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
<div className="form-group col-md-3">
<label>Mileage:</label>
<select className="custom-select" onChange={handleChange}>
<option value=''>Please select...</option>
{getCarMileage.map((data, key) => <option value={data.value} key={key}>{data.name}</option>)}
</select>
</div>
</div>
<div className="form-row">
<div className="form-group col-md-3">
<label>Car Trim:</label>
<select className="custom-select" onChange={handleChange}>
<option value=''>Please select...</option>
{getCarTrim.map((data, key) => <option value={data.value} key={key}>{data.name}</option>)}
</select>
</div>
<div className="form-group col-md-3">
<label>Email:</label>
<input type="email" placeholder="Email" className="custom-select" />
</div>
<div className="form-group col-md-3">
<label>Phone no:</label>
<input type="number" placeholder="Phone no" className="custom-select" />
</div>
</div>
<div className="container-buttons">
<Button className="mr-4" variant="light">
Search
</Button>
<Button variant="dark" onClick={handleReset}>Clear</Button>
</div>
</Container>
</div>
);
};
export default CarRequests;
The thing you are doing wrong is in handleReset function you are taking the event and you are setting the target value to empty which is ideally wrong.
In order to correct it we need to understand how the flow is working, you are using handleChange function in order to set the values to your state.
So in order to reset it you need to reset the value of the state only.
So the code becomes like this:
const handleReset = () => {
setValue("");
}
Now this will reset the value of your state variable and also use your state variable in your select method which will resolve the problem.
<select value={value}>
<option></option>
.
.
</select>
To make dynamic field working:
function App() {
const [value, setValue] = useState({});
const arr = ["hello", "cra"];
const arr2 = [
{
name: "hello",
id: "1",
},
{
name: "test2",
id: "2",
},
];
const handleChange = ({ target: { value: val, name } }) => {
setValue({ ...value, [name]: val });
};
const resetValue = () => {
setValue({});
};
console.log(value);
return (
<div id="wrapper">
<select
name="select1"
value={value.select1 || ""}
onChange={handleChange}
>
<option value=""></option>
{arr.map((val) => {
return <option value={val}>{val}</option>;
})}
</select>
<select
name="select2"
value={value.select2 || ""}
onChange={handleChange}
>
<option value=""></option>
{arr2.map(({ name, id }) => {
return <option value={id}>{name}</option>;
})}
</select>
<button onClick={resetValue}>Reset</button>
</div>
);
}
Or else you can initialise the value in your state as well like this
const [value, setValue] = useState({select1: "" , select2: ""});
which could further be used dynamically in your select tag for name attributes.
function App() {
const [value, setValue] = useState({ select1: "", select2: "" });
const arr = ["hello", "cra"];
const arr2 = [
{
name: "hello",
id: "1",
},
{
name: "test2",
id: "2",
},
];
const handleChange = ({ target: { value: val, name } }) => {
setValue({ ...value, [name]: val });
};
const resetValue = () => {
setValue({
select1: "",
select2: "",
});
};
console.log(value);
return (
<div id="wrapper">
<select name="select1" value={value.select1} onChange={handleChange}>
<option value=""></option>
{arr.map((val) => {
return <option value={val}>{val}</option>;
})}
</select>
<select name="select2" value={value.select2} onChange={handleChange}>
<option value=""></option>
{arr2.map(({ name, id }) => {
return <option value={id}>{name}</option>;
})}
</select>
<button onClick={resetValue}>Reset</button>
</div>
);
}
Seems you are trying to store multiple values in the value . don't use the word value there. I have tried to change it to [formValue, setFormValue]
Change 1:
let [formValue, setFormValue] = useState({
textfield1: '',
dropdownfield2: ''});
Change 2 - for dropdown changed values:
const handlDropDownChange = (event, value) => {
setFormValue({
...formValue,
['dropdownfield2']: value,
});
}
Change 3 - for mapping dropdown values from state, also use this to map to dropdown value:
formValue.dropdownfield2
Change 4 - for text field changes:
onChange={e => {
updateFieldMyForm(e);
}}
const updateFieldMyForm= e => {
setFormValue({
...formValue,
[e.target.name]: e.target.value
});
};
Note this will work for all text fields - just make sure that the name of this textfield matches the name used in the useState statement like - textfield1
Change 5 - to reset the whole thing at the end/submission
EDIT - 1
const handleReset = () => { setFormValue({ textfield1: "", dropdownfield2: "" }); };
Spread operator is the key in steps 2 & 4 [triple dots - ...] - let me know if you still have challenges.
I am trying to use onClick function on react.js HTML select option and it works perfectly on Firefox but not on Chrome. How can I make it work in Chrome? Here is my code so far:
import React, { Component } from "react";
import DateRangePicker from "react-daterange-picker";
import "react-daterange-picker/dist/css/react-calendar.css";
import originalMoment from "moment";
export class Filter extends Component {
constructor(props, context) {
super(props, context);
this.state = {
isOpen: false,};
}
onToggle = () => {
this.setState({ isOpen: !this.state.isOpen });
};
render() {
return (
<div className="filter_range">
<select
class="form-control donn"
name="today"
>
<option selected disabled hidden>
Choose{" "}
</option>
<option value="today">Today</option>
<option value="yesturday">Yesterday</option>
<option>Last Week</option>
<option value="month">Last Month</option>
<option>Last Quarter</option>
<option value="year">Last Year</option>
<option value="">Overall</option>
<option value="" onClick={this.onToggle}>
Custom
</option>
</select>
{this.state.isOpen && (
<DateRangePicker
value={this.props.value}
onSelect={this.props.change}
singleDateRange={true}
isOpen={false}
maximumDate={new Date()}
closeCalendar={true}
numberOfCalendars={2}
showLegend={true}
locale={originalMoment().locale()}
/>
)}
</div>
);
}
}
export default Filter;
Try to use onChange instead of onClick for select element.
<select class="form-control donn" name="today" onChange={handleChange}>
Just add value to your custom option and check for it in the if statement
<option value="custom">
Custom
</option>
export class Filter extends Component {
constructor(props, context) {
super(props, context);
this.state = {
isOpen: false,
};
}
handleChange = (event) => {
if (event.target.value === "custom") {
this.setState({ isOpen: !this.state.isOpen });
}
};
render() {
return (
<div className="filter_range">
<select class="form-control donn" name="today" onChange={handleChange}>
<option selected disabled hidden>
Choose{" "}
</option>
<option value="today">Today</option>
<option value="yesturday">Yesterday</option>
<option>Last Week</option>
<option value="month">Last Month</option>
<option>Last Quarter</option>
<option value="year">Last Year</option>
<option value="">Overall</option>
<option value="custom">
Custom
</option>
</select>
{this.state.isOpen && (
<DateRangePicker
value={this.props.value}
onSelect={this.props.change}
singleDateRange={true}
isOpen={false}
maximumDate={new Date()}
closeCalendar={true}
numberOfCalendars={2}
showLegend={true}
locale={originalMoment().locale()}
/>
)}
</div>
);
}
}
export default Filter;
Option onClick - Unnecessary
You can put onChange in the select tag
The select onChange trigerd when option is clicked (changed).
You can have a child component that only renders the option tag. You actually don't need to add an event handler to the option tag. The select onChange event get called automatically once an option tag is clicked (passing it's value with it).
See the example here: https://codepen.io/gaearon/pen/JbbEzX?editors=0010
I am new on React.
I have a condition which is to loop the form, please help me
Here is the code:
this.state.products.map(product => {
<form onSubmit={this.handleSubmit}>
<select name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" onClick={() => this.handleSubmit} />
</form>
});
If there was 3 form, how to get the selected value from clicked submit button form?
Or is there another simple way?
Thank you
One method would be changing how your onSubmit function is handled.
So you could pass which index of products you are submitting like so
this.state.products.map((product, i) => {
<form onSubmit={event => this.handleSubmit(event, i)}>
<select name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" onClick={() => this.handleSubmit} />
</form>
});
It also looks like your form is uncontrolled, which another possibly is having the select change a value in state.
<select name="size" onChange={e => this.handleChange(e, i)} className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
and in your handleChange, you would change a value in state that would correspond to the product from your state.
You can use a ref to get form values from the DOM.
Here you need one ref per product, so you could use the index of product to save the ref and also to submit de form.
class Example extends Component {
constructor(props) {
super(props);
this.state = {
products: [],
};
this.selectByProduct = {};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event, productIndex) {
event.preventDefault();
const size = this.selectByProduct[productIndex].value;
console.log(`you submitted the size ${size} of product ${productIndex}`)
}
render() {
return this.state.products.map((product, i) => (
<form onSubmit={event => this.handleSubmit(event, i)}>
<select ref={select => this.selectByProduct[i] = select} name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" />
</form>
));
}
}
I would like to use addResults option in bootstrap-select to add new items. I should be prompted to add search string, but I get default message No Results.
jsfiddle
component.jsx
class TodoApp extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
$(this.selectPicker).selectpicker({
liveSearch: true,
addResults: true,
});
}
render() {
return (
<div>
<select className="form-control" data-width="100%" ref={el => (this.selectPicker = el)}>
<optgroup label="Group 1">
<option defaultValue>Team</option>
<option value="1">AAA</option>
</optgroup>
<optgroup label="Group 2">
<option value="2">BAC</option>
<option value="3">BAY</option>
</optgroup>
<optgroup label="Group 3">
<option value="4">DACA</option>
</optgroup>
</select>
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))