Got the error invalid input syntax for integer - javascript

Faced a problem with incorrect syntax when executing the get method to the database. The error is due to an attempt to put string data into integer, but I can't figure out where it's happening.
I think this is happening somewhere in the code below, please help me find where:
`
const Admin = () => {
const [fumoVisible, setFumoVisible] = useState(false);
const [searchFumo, setSearchFumo] = useState("");
const [searchedFumo, setSearchedFumo] = useState([]);
useEffect(() => {
getAllFumoInAdminPage(searchFumo, currentPage, filter).then(
({ count, rows }) => {
setSearchedFumo(rows);
setCount(count);
}
);
}, [currentPage]);
useEffect(() => {
getAllFumoInAdminPage(searchFumo, 1, filter).then(({ count, rows }) => {
setSearchedFumo(rows);
setCount(count);
setCurrentPage(1);
});
}, [filter]);
const fetchFumo = () => {
getAllFumoInAdminPage(searchFumo, currentPage, filter).then(
({ count, rows }) => {
setSearchedFumo(rows);
setCount(count);
}
);
};
return (
<Container className="d-flex flex-column">
<InputGroup className="mb-3">
<Form.Control
aria-label="Default"
aria-describedby="inputGroup-sizing-default"
value={searchFumo}
onChange={(e) => setSearchFumo(e.target.value)}
placeholder="Enter name..."
/>
<Button onClick={fetchFumo} variant="outline-dark" className="ml-2">
Search
</Button>
</InputGroup>
<ListGroup>
{searchedFumo &&
searchedFumo.map(({ id, img, price, name }) => {
return (
<ListGroup.Item className="mt-3" key={id}>
//
</ListGroup.Item>
);
})}
</ListGroup>
</Container>
);
};
export default Admin;
`

Related

Formik field values arn't being passed from React Context

I have a Formik form that is using a progressive stepper and have multiple fields across different components, thus requiring the need to store the values in React Context. However none of the field values are being passed, so when I click submit, all values are empty strings and the validation fails. You can see on each Formik Field i am setting the value as {state.[field]}, which comes from the Context, so I believe something is going wrong here. Can anyone see what I'm doing wrong?
Thanks a lot
Here is my parent component
const AddSongPage = () => {
const { state, dispatch } = useUploadFormContext();
const initialValues = {
name: "",
};
const { mutate: handleCreateTrack } = useCreateSyncTrackMutation(
gqlClient,
{}
);
const handleSubmit = (values: any) => {
handleCreateTrack(
{
...values,
},
{
onSuccess() {
console.log("Track added succesfully");
},
}
);
};
const validate = Yup.object({
name: Yup.string().required("Song name is required"),
description: Yup.string().optional(),
});
return (
<Layout headerBg="brand.blue">
<Formik
onSubmit={(values) => handleSubmit(values)}
initialValues={initialValues}
validationSchema={validate}
>
<Form>
<Box> {state.activeStep === 1 && <Step1 />}</Box>
<Box> {state.activeStep === 2 && <Step2 />}</Box>
<Box> {state.activeStep === 3 && <Step3 />}</Box>
<Button type={"submit"}>Submit</Button>
</Form>
</Formik>
</Layout>
);
};
Here is step 1
const Step1 = () => {
const { state, dispatch } = useUploadFormContext();
const onInputChange = (e: FormEvent<HTMLInputElement>) => {
const inputName = e.currentTarget.name;
dispatch({
type: "SET_UPLOAD_FORM",
payload: {
[inputName]: e.currentTarget.value,
},
});
};
return (
<Stack spacing={4}>
<Field name={"name"}>
{({ field, form }: any) => (
<FormControl isInvalid={form.errors.name && form.touched.name}>
<Input
{...field}
onChange={onInputChange}
value={state.name}
/>
</FormControl>
)}
</Field>
<Field name={"description"}>
{({ field, form }: any) => (
<FormControl isInvalid={form.errors.name && form.touched.name}>
<Input
{...field}
onChange={onInputChange}
value={state.description}
/>
</FormControl>
)}
</Field>
</Stack>
);
};
export default Step1;

How to add child array input field dynamically in React JS

Here is my code
const useStyles = makeStyles((theme) => ({
root: {
'& .MuiTextField-root': {
margin: theme.spacing(1)
},
},
button: {
margin: theme.spacing(1)
}
}))
function CreateCourse() {
const classes = useStyles();
const [sectionFields, setSectionFields] = useState([{
sectionName: '',
overview: '',
videoContents: [{
videoName: '', videoUrl: ''
}]
}])
function handleChangInput(index, event) {
const values = [...sectionFields];
values[index][event.target.name] = event.target.value;
setSectionFields(values);
}
function handleChangVideoInput(index, i, event) {
const values = [...sectionFields];
values[index].videoContents[i][event.target.name] = event.target.value;
setSectionFields(values);
console.log(index, event.target.name)
}
const handleSubmit = (event) => {
event.preventDefault();
console.log("Input Field ", sectionFields)
}
const handleRemoveFields = (index) => {
const values = [...sectionFields];
values.splice(index, 1)
setSectionFields(values)
}
const handleAddFields = () => {
setSectionFields([...sectionFields, {
sectionName: '',
overview: '',
videoContents: [{videoName: '', videoUrl: ''}]
}])
}
return (
<div className='container mb-5'>
<Container>
<h1>Add New Member</h1>
<form className={classes.root} onSubmit={handleSubmit}>
{sectionFields.map((inputField, index) => (
<div key={index}>
<TextField
name="sectionName"
label="Section Name"
variant="filled"
value={inputField?.sectionName}
onChange={event => handleChangInput(index, event)}
/>
<TextField
name="overview"
label="Section Overview"
variant="filled"
value={inputField?.overview}
onChange={event => handleChangInput(index, event)}
/>
<IconButton onClick={() => handleRemoveFields(index)}>
<RemoveIcon/>
</IconButton>
<IconButton onClick={handleAddFields}>
<AddIcon/>
</IconButton>
{inputField?.videoContents?.map((v, i) => (
<div key={i}>
<TextField
name="videoName"
label="Enter Video Name"
variant="filled"
value={v.videoName}
onChange={event => handleChangVideoInput(index, i, event)}
/>
<TextField
name="videoUrl"
label="Enter Video Url"
variant="filled"
value={v.videoUrl}
onChange={event => handleChangVideoInput(index, i, event)}
/>
</div>
))}
</div>
))}
<Button
className={classes.button}
variant='contained'
color='primary'
type='submit'
endIcon={<Icon/>}
onClick={handleSubmit}
>
SEND
</Button>
</form>
</Container>
</div>
);
}
export default CreateCourse;
Output in Screenshot
when i click on plus icon creates a new input like
But I want one sectionName has many videoName and videoUrl like I want to create plus icon on the videoUrl side and when user clicks plus icon, it creates many videoName and videoUrl as many as user wants and if user clicks section then it creates one section row with one video row. How can I solve this using react?
First of all, when you use the current value of a state in order to calculate the new state value, it's preferable to use a callback function. This way it's not influenced by re-renders and guarantees the calculation uses the most updated state value.
So assuming you have
const [state, setState] = useState([]);
Don't use:
const next = [...state, newElement];
setState(next);
But instead, use:
setState((previous) => [...previous, newElement]);
In order to add more fields into a nested array, you can update the state like this:
function addToSection(i) {
setSectionFields((prev) => (
const updatedSection = {
...prev[i],
videoContents: [
...prev[i].videoContents,
{ videoName: '', videoUrl: '' },
],
};
return prev.map((section, index) => {
return index === i ? updatedSection : section;
});
);
}
After many hours of trying finally i did it and thanks to #GalAbra , he saves my lot of time and i post this because if it helps to anyone
import React, {useState} from "react";
import Container from "#material-ui/core/Container";
import {TextField} from "#material-ui/core";
import Icon from "#material-ui/icons/Send";
import {makeStyles} from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
import IconButton from "#material-ui/core/IconButton";
import RemoveIcon from '#material-ui/icons/Delete';
import AddIcon from "#material-ui/icons/Add";
const useStyles = makeStyles((theme) => ({
root: {
'& .MuiTextField-root': {
margin: theme.spacing(1)
},
},
button: {
margin: theme.spacing(1)
}}))
function CreateCourse() {
const classes = useStyles();
const [sectionFields, setSectionFields] = useState([{
sectionName: '',
overview: '',
videoContents: [{
videoName: '', videoUrl: ''
}]}])
function handleChangInput(index, event) {
const values = [...sectionFields];
values[index][event.target.name] = event.target.value;
setSectionFields(values);
}
function handleChangVideoInput(index, i, event) {
const values = [...sectionFields];
values[index].videoContents[i][event.target.name] = event.target.value;
setSectionFields(values);
console.log(index, event.target.name)
}
const handleSubmit = (event) => {
event.preventDefault();
console.log("Input Field ", sectionFields)
}
const handleRemoveFields = (index) => {
const values = [...sectionFields];
if(index > 0) values.splice(index, 1)
setSectionFields(values)
}
const handleRemoveVideoFields = (index, i) => {
const values = [...sectionFields];
if(i > 0)
values[index].videoContents.splice(i, 1)
setSectionFields(values)
}
const handleAddFields = (index) => {
setSectionFields((prevState => (
[...prevState, {
videoContents: [{videoName: '', videoUrl: ''}]
}]
)))
}
const handleAddVideoFields = (i) => {
setSectionFields(prev => {
const updatedSection = {
...prev[i],
videoContents: [
...prev[i].videoContents,
{videoName: '', videoUrl: ''},
],
};
return prev.map((section, index) => {
return index === i ? updatedSection : section;
});
})
}
return (
<div className='container mb-5'>
<Container>
<form className={classes.root} onSubmit={handleSubmit}>
{sectionFields.map((inputField, index) => (
<div key={index}>
<p className='mb-0 mt-3 ml-2'>Enter Section Name</p>
<TextField
name="sectionName"
label="Section Name"
variant="filled"
value={inputField?.sectionName}
onChange={event => handleChangInput(index, event)}
/>
<TextField
name="overview"
label="Section Overview"
variant="filled"
value={inputField?.overview}
onChange={event => handleChangInput(index, event)}
/>
<IconButton onClick={() => handleRemoveFields(index)}>
<RemoveIcon/>
</IconButton>
<IconButton onClick={() => handleAddFields(index)}>
<AddIcon/>
</IconButton>
{inputField?.videoContents?.map((v, i) => (
<div key={i}>
<TextField
name="videoName"
label="Enter Video Name"
variant="filled"
value={v.videoName}
onChange={event => handleChangVideoInput(index, i, event)}
/>
<TextField
name="videoUrl"
label="Enter Video Url"
variant="filled"
value={v.videoUrl}
onChange={event =>
handleChangVideoInput(index, i, event)}
/>
<IconButton onClick={() =>
handleRemoveVideoFields(index, i)}>
<RemoveIcon/>
</IconButton>
<IconButton onClick={() =>
handleAddVideoFields(index)}>
<AddIcon/>
</IconButton>
</div>
))}
</div>
))}
<Button
className={classes.button}
variant='contained'
color='primary'
type='submit'
endIcon={<Icon/>}
onClick={handleSubmit}
>
SEND
</Button>
</form>
</Container>
</div>
);
}
export default CreateCourse;

Remove item from list with redux/ hooks not working

I am making a watchlist component using redux/react/hooks. Component is in 3 pieces (form to add to list, container to map over securities, and security to display each item)
So far I have been able to add values by dispatching addStock in the form component. I tried to do the same thing in security component for deleteStock but it isn't working/ reloads page.
reducer:
const stockSelector = (state = STOCK_STATE, action) => {
switch (action.type) {
case STOCK_SELECTED:
return action.payload;
case FETCH_STOCK_LIST:
return { ...state, watchlist: action.payload.select, title: action.payload.name, loading: false};
case STOCK_LIST_LOADING:
return {...state, loading: true}
case ADD_STOCK:
return { ...state, watchlist: [action.payload, ...state.watchlist] };
case DELETE_STOCK:
return {
...state,
watchlist: [
...state.watchlist.slice(0, action.payload),
...state.watchlist.slice(action.payload + 1)
],
};
default:
return state;
}
action
export const deleteStock = (payload) => ({
type: DELETE_STOCK,
payload,
});
watchlist component
const Watchlist = ({selected, watchlists, number}) => {
const dispatch = useDispatch();
const [taskList, setTaskList] = useState(['AAPL', 'MSFT', 'AMZN'])
const [list, setList] = useState(selected)
const [allList, setAllList] = useState(watchlists)
const [selectNumber, setSelectNumber] = useState(number)
const selectWatchlist = async () => {
setList(selected)
setSelectNumber(number)
}
useEffect(() => {
selectWatchlist()
.then(dispatch(fetchStockList(selectNumber)))
}, []);
return (
<React.Fragment>
<Col className="watchlist-master-col">
<Row className="watchlist-form-row">
<Col>
<AddWatchlistForm className="watchlist-form" />
</Col>
</Row>
<Row className="watchlist-list-row">
<ListSecurityContainer
list={taskList}
className="watchlist-list"
number={number}
/>
</Row>
<Row>
<Modal className='modalOne' />
</Row>
</Col>
<Modal />
</React.Fragment>
)
}
const mapStateToProps = (state) => {
console.log(state)
return {
selected: state.Watchlist.stock.title,
watchlists: state.Watchlist.watchlist.watchlist,
watchlist: state.Watchlist.stock.watchlist,
number: state.Watchlist.watchlist.number,
}
}
container
const ListSecurityContainer = ({loading, stocks}) => {
const dispatch = useDispatch();
const handleCloseTask = (id) => {
dispatch(deleteStock(id))
}
if (loading === false) {
return (
<React.Fragment>
<Col>
{stocks.map((value, index) => (
<Security
key={stocks[index]}
id={index}
{...value}
name={value}
// onClose={handleCloseTask}
className="security-elem"
/>
))}
</Col>
</React.Fragment>
);
}
return <div>Loading...</div>
}
const mapStateToProps = (state) => {
console.log(state.Watchlist.stock.watchlist)
return {
stocks: state.Watchlist.stock.watchlist,
loading: state.Watchlist.stock.loading
}
}
security
const Security = (value) => {
const dispatch = useDispatch();
const [taskName, setTaskName] =useState(value.name)
const removeTask = () => {
dispatch(deleteStock(taskName))
}
return (
<div className="list-group-item">
{value.name}
<button onClick={removeTask()} style={{ float: 'right' }}>
<i className="glyphicon glyphicon-remove"></i>
</button>
</div>
);
}
Fixed this by correcting the issues listed in the comments and also fixing a type that I had in my constants.js file.
const Security = ({index, name}) => {
const dispatch = useDispatch();
const [taskName, setTaskName] =useState(name)
const removeTask = (e) => {
e.stopPropagation()
dispatch(removeStock(index))
}
return (
<Row className="list-group-item">
<div className="item-titles">
{name}
</div>
<button onClick={() => dispatch(removeStock(index))} className="remove-item">
<i className="glyphicon glyphicon-remove"></i>
</button>
</Row>
);
}

Trying to learn React hooks and don't understand why this checkbox behavior is broken?

The component loads with 3 todos. If you check the middle one it should get a line through it. Then if you click the [x] button on it, it goes away, but for some reason the todo below it gets checked.
Anyone see the reason for this?
const Todo = props => {
const markCompleted = (checked, index) => {
const newTodos = [...props.todos];
newTodos[index].isCompleted = checked;
props.setTodos(newTodos);
};
const deleteTodo = index => {
const newTodos = [...props.todos];
newTodos.splice(index, 1);
props.setTodos(newTodos);
};
return (
<div
style={{ textDecoration: props.todo.isCompleted ? 'line-through' : '' }}
className="todo"
>
<input
type="checkbox"
onChange={e => markCompleted(e.target.checked, props.index)}
/>
{props.todo.text}
<button onClick={() => deleteTodo(props.index)}>x</button>
</div>
);
};
const TodoForm = props => {
const [value, setValue] = React.useState('');
const addTodo = e => {
e.preventDefault();
if (!value) return;
const newTodos = [...props.todos, { text: value }];
props.setTodos(newTodos);
setValue('');
};
return (
<form onSubmit={addTodo}>
<input
type="text"
className="input"
value={value}
onChange={e => setValue(e.target.value)}
/>
</form>
);
};
const App = () => {
const [todos, setTodos] = React.useState([
{ text: 'Learn about React', isCompleted: false },
{ text: 'Meet friend for lunch', isCompleted: false },
{ text: 'Build really cool todo app', isCompleted: false }
]);
return (
<div className="app">
<div className="todo-list">
{todos.map((todo, index) => (
<Todo {...{ key: index, todo, index, todos, setTodos }} />
))}
<TodoForm {...{ todos, setTodos }} />
</div>
</div>
);
};
ReactDOM.render(
<App />
, document.querySelector('#react'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
The previously checked checkbox remains rendered. You should explicitly set its checked status instead, so that it's taken from the props every time, rather than possibly from user input:
checked={props.todo.isCompleted}
You also should use functional methods like filter instead of using mutating methods like splice, and newTodos[index].isCompleted = checked; is mutating the todo object - [...props.todos] only shallow clones the array of objects. Spread the todos around the changed object into the array passed to setTodos instead.
props.setTodos([
...todos.slice(0, index),
{ ...todos[index], isCompleted: checked },
...todos.slice(index + 1),
]);
const Todo = props => {
const markCompleted = (checked, index) => {
const { todos } = props;
props.setTodos([
...todos.slice(0, index),
{ ...todos[index], isCompleted: checked },
...todos.slice(index + 1),
]);
};
const deleteTodo = index => {
props.setTodos(props.todos.filter((todo, i) => i !== index));
};
return (
<div
style={{ textDecoration: props.todo.isCompleted ? 'line-through' : '' }}
className="todo"
>
<input
type="checkbox"
onChange={e => markCompleted(e.target.checked, props.index)}
checked={props.todo.isCompleted}
/>
{props.todo.text}
<button onClick={() => deleteTodo(props.index)}>x</button>
</div>
);
};
const TodoForm = props => {
const [value, setValue] = React.useState('');
const addTodo = e => {
e.preventDefault();
if (!value) return;
const newTodos = [...props.todos, { text: value }];
props.setTodos(newTodos);
setValue('');
};
return (
<form onSubmit={addTodo}>
<input
type="text"
className="input"
value={value}
onChange={e => setValue(e.target.value)}
/>
</form>
);
};
const App = () => {
const [todos, setTodos] = React.useState([
{ text: 'Learn about React', isCompleted: false },
{ text: 'Meet friend for lunch', isCompleted: false },
{ text: 'Build really cool todo app', isCompleted: false }
]);
return (
<div className="app">
<div className="todo-list">
{todos.map((todo, index) => (
<Todo {...{ key: index, todo, index, todos, setTodos }} />
))}
<TodoForm {...{ todos, setTodos }} />
</div>
</div>
);
};
ReactDOM.render(
<App />
, document.querySelector('#react'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

React "TypeError: product.name.includes(...).map is not a function" when attempting to filter through product list

I have a React application that displays a list of products when getting product data from a database using an axios.get call. That part works perfectly, but today I've tried implementing a search feature to only display product names that matches the search query but when I attempt to type even a single letter the application crashes and I get this:
TypeError: product.name.includes(...).map is not a function
function productList() {
40 | if(searchTerm) {
> 41 | return products.filter(product => product.name.includes(searchTerm).map(function(currentProduct, i) {
| ^ 42 | return <Product product={currentProduct} key={i} />;
43 | }));
44 | } else {
How can I implement this correctly? I was trying to follow this previously answered question as a guide.
productListPublic.js:
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { CardColumns, Card, Row, Col, ListGroup, Form } from "react-bootstrap";
import axios from "axios";
function ProductListPublic(props) {
const [isError, setIsError] = useState(false);
const [products, setProducts] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const Product = props => (
<Card>
<Row>
<Col md={{ span: 4 }}>
<Card.Title className="mt-4 text-center">
<Link to={`/products/list/${props.product._id}/`}>{props.product.name}</Link>
</Card.Title>
</Col>
<Col md={{ span: 8 }}>
<ListGroup>
<ListGroup.Item className="text-truncate">{props.product.description}</ListGroup.Item>
<ListGroup.Item>{props.product.stock} in stock</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</Card>
)
useEffect(() => {
axios.get("http://localhost:4000/products/")
.then(res => {
setProducts(res.data);
}).catch(function(err) {
setIsError(true);
})
}, []);
function productList() {
if(searchTerm) {
return products.filter(product => product.name.includes(searchTerm).map(function(currentProduct, i) {
return <Product product={currentProduct} key={i} />;
}));
} else {
return products.map(function(currentProduct, i) {
return <Product product={currentProduct} key={i} />;
})
}
}
return (
<div className="text-center">
<Form>
<Form.Row>
<Form.Group as={Col}>
<Form.Label htmlFor="formSearch">Search Products</Form.Label>
<Form.Control
controlid="formSearch"
type="text"
value={searchTerm}
onChange={e => {
setSearchTerm(e.target.value);
}}
placeholder="Product Name"
/>
</Form.Group>
</Form.Row>
</Form>
<h2>Products List</h2>
<CardColumns>
{ productList() }
</CardColumns>
{ isError &&<p>Something went wrong with getting the products!</p> }
</div>
)
}
export default ProductListPublic;
Close the filter parentheses then use map on the resultant list.
return products.filter(product => product.name.includes(searchTerm)).map((currentProduct, i) => {
return <Product product={currentProduct} key={i} />;
});

Categories

Resources