Input values in state as route params - javascript

I want to send input values as route params to server. Should I write a function to encode values? I'm trying to do this without any libraries..
By coincidence, I mistyped localhost 8000,then the browser appended localhost 3000 url to 8000 and only then did the set Search Params work and I did get the values appended to as route params but the url of server wasn't right one, obviously.
Here is my code:
import axios from 'axios';
import React, { useState } from 'react';
import { useSearchParams } from 'react-router-dom';
const AddProductForm = ({ id }) => {
let [searchParams, setSearchParams] = useSearchParams();
const [input, setInput] = useState({
title: '',
price: '',
rating: '',
description: '',
});
const handleSubmit = (e) => {
e.preventDefault();
setSearchParams(input)
axios
.put(`http://localhost:8080/api/v1/products/${id}?` + searchParams)
.then((res) => console.log(res))
.catch((err) => console.log(err));
};
const onChange = (e) => {
//function to handle change of each input
}
return (
<div className='container' >
<form className='form' onSubmit={handleSubmit}>
<div className='form_inputs'>
<h1>Edit Product</h1>
<div className='flex-column'>
<label>Add new title</label>
<input
type='text'
value={input.title}
onChange={onChange}
name='title'
placeholder='Title'
/>
</div>
<div className='flex-column'>
<label>Add new price</label>
<input
type='number'
value={input.price}
onChange={onChange}
name='price'
placeholder='Price'
/>
</div>
//All other inputs
<button className='btn-block' type='submit'>
Create
</button>
</form>
</div>
);
};
export default AddProductForm;
On Submitting I only get empty object URLSearchParams{}

The setSearchParams function works like the navigate function in that it effects a navigation action but only updates the current URL's search string. The code isn't actually updating the searchParams variable.
You want to take the input state and create a new URLSearchParams object.
Example:
const handleSubmit = (e) => {
e.preventDefault();
const searchParams = new URLSearchParams(input);
axios
.put(`http://localhost:8080/api/v1/products/${id}?${searchParams.toString()}`)
.then(console.log)
.catch(console.warn);
};

Related

Axios post method - not getting UseState data

Working on Full stack app, client side is giving problems mainly using axios module. The axios post method is not posting const data in the UseState from react. The server shows entry as primary ID is created but no other data is entered, it is showing as null.
This is the client side for Add Book Form:
import React from 'react'
import { useState } from 'react'
import axios from 'axios'
//import { useNavigate } from 'react-router-dom'
const Add = () => {
const [bookData, setBook] = useState({
title: '',
author: '',
details: '',
price: null,
cover: '',
userId: 1
})
const [error, setError] = useState(false)
//const navigate = useNavigate()
const dataEntry = (event) => {
setBook((previous) => ({...previous, [event.target.name]: event.target.value }))
}
const eventClick = async (event) => {
event.preventDefault()
try {
const result = await axios.post('/books', bookData) //error occurs here
console.log(result)
//navigate('/login')
} catch (error) {
setError(error.response.data)
}
}
return (
<div className='form'>
<h1>Add New Book</h1>
<form>
<input required type={'text'} placeholder={'title'} name={'title'} onChange={dataEntry} />
<input required type={'text'} placeholder={'author'} name={'author'} onChange={dataEntry} />
<input required type={'text'} placeholder={'details'} name={'details'} onChange={dataEntry} />
<input required type={'number'} placeholder={'price'} name={'price'} onChange={dataEntry} />
<input required type={'text'} placeholder={'cover'} name={'cover'} onChange={dataEntry} />
<button onClick={eventClick}>ADD</button>{error && "Something went wrong!"}
</form>
</div>
)
}
export default Add
I tried changing the Sequelize model structure and still getting no data entered. I've ensured my client side folder in the package.json has the 'proxy': 'http://localhost:5000/api/' route set up and still it's giving errors

How to set the initial state value after fetching data to update a form in react

I'm new to react and I've tried to fetch data using "setData" and then using the state variable "data" to set the values of title , desc and author but I'm getting them as undefined. After setting the initial states to empty I've set the values of the input fields to what I had got from the "data" state and when I submit the form only the fields in which the changes are made were updated the rest of the fields had "undefined" values i.e when I submitted the form to update it looked like this {title:undefined,desc:undefined,author:"person1"}, I'm unable to set the initial state values to input field values.
EditBlog.js
import React, { useState, useEffect } from "react"
import { useParams, useHistory } from "react-router-dom"
const EditBlog = () => {
const { id } = useParams()
useEffect(() => {
fetch('http://localhost:8000/values/' + id)
.then((res) => {
return res.json()
})
.then((data) => {
setData(data)
})
}, [id])
const [data, setData] = useState({})
const [title, setEditTitle] = useState()
const [desc, setEditDesc] = useState()
const [author, setEditAuthor] = useState()
const history = useHistory()
const updateHandler = (e) => {
e.preventDefault()
const updatedBlog = { title, desc, author }
fetch('http://localhost:8000/values/' + id, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(updatedBlog)
})
.then(() => {
console.log(updatedBlog)
history.push("/")
})
}
return (
<React.Fragment>
<div>
<h1>Edit Blog</h1>
<form onSubmit={updateHandler} className="new-blog">
<label>Blog Title</label>
<div className="input-box">
<input
onChange={(e) => setEditTitle(e.target.value)}
type="text"
defaultValue={data.title}
className="inputField"
/>
</div>
<label>Blog Body</label>
<div className="input-box">
<textarea
onChange={(e) => setEditDesc(e.target.value)}
cols="64"
defaultValue={data.desc}
/>
</div>
<label>Blog Author</label>
<div className="input-box">
<input
onChange={(e) => setEditAuthor(e.target.value)}
className="inputField"
type="text"
defaultValue={data.author}
/>
</div>
<button>Save</button>
</form>
</div>
</React.Fragment>
)
}
export default EditBlog
You're confusing yourself by trying to keep two copies of the same data in state. Reduce the state to just the one object you're editing (and give it initial values for the inputs, so nothing is undefined):
const [data, setData] = useState({
title: '',
desc: '',
author: ''
});
Have your inputs use and update the values in that state object:
<input
onChange={(e) => setData({...data, title: e.target.value})}
type="text"
value={data.title}
className="inputField"
/>
Note the use of value={data.title} so the input always shows the current value, and the new onChange which updates the same state being used and just changes the one value in that state object.
Then when you post the form, simply post the current state instead of building a new object from separately tracked values:
body: JSON.stringify(data)
In short, you don't need or want these:
const [title, setEditTitle] = useState()
const [desc, setEditDesc] = useState()
const [author, setEditAuthor] = useState()
Because you already have your data in data.
In useEffect add this code in .then block after setData(data):
setEditTitle(data.title)
setEditDesc(data.description)
setEditAuthor(data.author)
And replace defaultValue={data.title} with value={title} and the other two in the same way.
Note: I would say that The best approach is to avoid using states for your fields as you are already saving the state in useData. You should modify your code to avoid having three different state hooks.

React state not updating when sent to child component as a handleSubmit function

I am trying to update a searchResults state in dashboard.jsx.
My search form is in Header component, so I passed onSubmit function from Dashboard to Header.
onSubmit function contains state update.
The problem is that when I console log res, it shows the data that is receiving from spotify web api, but after I set the state using setState and console log it searchResults, it shows an empty array.
I am not sure why this is happening. When I go look up Chrome react dev tool, and browse the component, there is an array of objects that I got from API in the state.
Please HELP!!!
const Dashboard = ({ code }) => {
const [searchResults, setSearchResults] = useState([]);
const accessToken = useAuth(code);
const onSubmit = (search) => {
spotifyApi
.searchTracks(search) //
.then((res) => {
console.log(res.body);
setSearchResults(
res.body.tracks.items.map((track) => {
return {
artist: track.artists[0].name,
title: track.name,
uri: track.uri,
albumUrl: track.album.images[1],
};
})
);
});
};
const Header = ({ onSubmit }) => {
const inputRef = useRef();
const formRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
let result = inputRef.current.value;
formRef.current.reset();
onSubmit(result);
};
return (
<>
<div className={styles.header_left}>
<h2>wMusic</h2>
</div>
<form ref={formRef} className={styles.header_mid} onSubmit={handleSubmit}>
<input
ref={inputRef}
type='text'
className={styles.search}
placeholder='Search Songs/Artists'
/>
<button type='submit' className={styles.search_button}>
<BsSearch className={styles.search_icon} />
</button>
</form>
<div className={styles.header_right}>
<button className={styles.sign_out}>Sign Out</button>
</div>
</>
);
};
export default Header;

How to use setformdata to store data in form

I'm making a form and below is the format. As you can see I was in two cases (for storing in multistage form) and upon clicking next on the second form we call {onSubmitform}. The problem which you can see is while entering data in form, I'm facing where to store it i.e, {onChange}.
Also ~ please let me know if this was {onSubmitform} will work to send data to the backend.
import React, { useEffect, useState } from 'react';
const Rider_Signup = ()=>{
const [step, setstep] = useState(1);
const [formdata, setFormData] = useState({zipcode:"", email:"",name:"",location:"", dob:"",phone:"",sex:"", password:"",aadhar:""}); // use to hold input from user
const onSubmitform = async e =>{
e.preventDefault();
try{
const email=formdata.email;
console.log(email);
const body={email};
const response = await fetch("http://localhost:5000/api/service/signup",{
method:"POST",headers:{"Content-Type":"application/json"},
body:JSON.stringify(body)
})
const datainjson = await response.json();
window.location =`/driver/login`;
}catch(err){
console.log('Error')
}
}
const renderForm = () =>{
switch(step){
case 1: return <div className="admin_form_div">
<h1 className="form_header">Hey ! </h1>
<center>
<form action="/initial" id="admin_form" name="admin_form">
<label for="Email" className="label">Enter the Email</label><br/>
<input type="email" name="name" className="Email" value={formdata.email} onChange={e =>{console.log(formdata.email)
setFormData(formdata.email=(e.target.value))}} placeholder="email#id.com" pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,}$" title="Please enter valid email" required />
<br/>
<br/>
<button onClick = {() => setstep(step+1)}>Submit</button>
</form>
</center>
</div>
case 2: return <div><h1>{formdata.email} </h1><button onClick = {() => setstep(step+1)}>Submit</button></div>
default: return <div> {onSubmitform}</div>
}
}
return (
renderForm()
)
};
export default Rider_Signup;
formdata is const and cant be reassigned,
formdata can only be changed with setFormData hook.
...formdata will save other fields when only the email is changing.
also, this is duplicated.
onChange={
e => {
console.log(formdata.email)
setFormData({ ...formdata, email: e.target.value })
}
}

How to input an existing value into an input field in React for an edit form

I have an existing Task with a title and a description, and I want to navigate to an edit form. By default I want the existing title and description values to populate the inputs using React. The important piece of this code I'm asking about is value={task.title}. Please ignore how the data is being pulled in (I'm new to React and I'm experimenting). The onChange and onSubmit handles work correctly, but the error obviously indicates I'm doing it wrong and it does cause occasional bugs.
I've tried abstracting those values into some sort of formValues state as well, but no matter how the values are being input, if the value={howeverIDoIt} is being directly manipulated I get the error.
import React, { useEffect, useState } from 'react';
import { HEADERS, TODO_URL } from '../urls';
import { useHistory, useParams } from 'react-router-dom';
const TaskEdit = () => {
const [task, setTask] = useState({});
const { id } = useParams();
const history = useHistory();
useEffect(() => {
fetch(`${TODO_URL}/api/tasks/${id}/`, {headers: HEADERS})
.then(response => response.json())
.then(responseJson => {
setTask(responseJson);
});
}, []);
const handleChange = (e) => {
setTask(e.target.value)
}
const handleSubmit = (e) => {
e.preventDefault();
const body = {
'title': e.target.form[0].value,
'description': e.target.form[1].value
}
fetch(
`${TODO_URL}/api/tasks/${id}/edit/`,
{
headers: HEADERS,
method: 'PUT',
body: JSON.stringify(body)
}
).then(res => res).catch(err => err);
history.push(`/task/${id}`)
}
return (
<form>
<div>
<label>Title</label>
<input type="text" onChange={handleChange} value={task.title} />
</div>
<div>
<label>Description</label>
<textarea onChange={handleChange} value={task.description}></textarea>
</div>
<button onClick={handleSubmit}>Submit</button>
</form>
);
}
export default TaskEdit;
I have tried putting in a default value for useState like so: useState({title: 'title', description: 'description'}) but that doesn't prevent the error, nor does adding this edit form into the Task.js component, where task is most definitely defined.
You have:
<input type="text" onChange={handleChange} value={task.title} />
Your handleChange method is:
const handleChange = (e) => {
setTask(e.target.value)
}
When your onChange fires, your task state will be set to a String (the value of <input />)
So when you are referencing task.title after your onChange fires, it will be undefined. The same is true for task.description.
Try this:
const handleTitleChange = (e) => {
setTask({...task, title: e.target.value})
}
const handleDescriptionChange = (e) => {
setTask({...task, description: e.target.value})
}
<input type="text" onChange={handleTitleChange} value={task.title} />
<textarea onChange={handleDescriptionChange} value={task.description} />
Alternatively, you could split up the task state to title and description, respectively.

Categories

Resources