Axios post method - not getting UseState data - javascript

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

Related

Input values in state as route params

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);
};

Next.js trying to push input value into json, but it doesn't work

Right there I'm trying to get value from inout, and after that change it in json.
Json file is correct, and value from it is also correct, so when I'm trying to output PcosData....Title - everything is okay
the serverside has also no problems, as in terminal i get (get & POST), and data which is in POST is also returning, that means - a) server gets input value b) backend is correct
so the problem. is in frontend, I think I'm doing something wrongg when I'm trying to push data in HandleSubmit or smth like that
import PcosData from "/data/pcos.json";
import {useEffect} from "react";
import { useState } from "react";
import bodyParser from "body-parser";
import util from "util";
const getBody = util.promisify(bodyParser.urlencoded());
export async function getServerSideProps({req, res}) {
await getBody(req, res);
console.log(req.method, req.body);
return {
props: {
// status
}
}
}
export default function adminPcos() {
const [title, setTitle] = useState(PcosData["pcos-first"].title);
const handleSubmit = (e) => {
// e.preventDefault();
PcosData["pcos-first"].title = title;
console.log(handleSubmit)
}
return (
<div>
<h1>hello world</h1>
{PcosData["pcos-first"].map((pcosdata) => (
<form onSubmit={handleSubmit} key={ pcosdata.id } method="post">
<input type="text" className="name" name="title" defaultValue={pcosdata.title} onChange={(e) => setTitle({text: e.target.value})}/>
<button type="submit">Submit</button>
</form>
))}
</div>
)
}

Is it normal for react to re-render component when using promise inside a function?

I'm in progress learning react and I have created an app with a login form. When the login form is submitted the login function passed to the component is executing twice as indicated in the console (logInUser – "running") even though the login button is only clicked once.
The function (loginUser) contains a promise blogService.setToken(xyz).then(xyz) and when the promise is removed the function only executes once.
While I have a method called setToken, this is not using a react state and so this shouldn't be contributing to the issue. I'm wondering why this the promise causing the component to re-render and if anyone could point me into the direction of documentation if promises cause a re-render. I can't seem to hit the right keywords to find the answer.
Can create a GitHub repo to share if that helps. Code below.
Cheers.
Console log
[Log] handleSubmit – "running"
[Log] handleSubmit – {token: "xxx", username: "xxx", name: "xxx"}
[Log] logInUser – "running"
[Log] logInUser: returnedObject – {token: "xxx", username: "xxx", name: "xxx"}
[Log] logInUser – "running"
App.js
import { useState, useEffect } from "react";
import blogService from "./services/blogs";
import LoginForm from "./components/Login";
//...
const App = () => {
const [user, setUser] = useState(null);
const logInUser = (returnedObj) => {
console.log("logInUser", "running");
if (returnedObj) {
console.log("logInUser: returnedObject", returnedObj);
// Causing a rerender
blogService.setToken(returnedObj.token)
.then(() => {
console.log('hello')
// then go and set the user
});
}
};
//...
return (
<div>
{user === null ? (
<div>
<h1>Login</h1>
<Notification message={notificationMessage} />
<LoginForm loggedInUser={logInUser} />
</div>
) : (
<div>
<h1>Logged in</h1>
</div>
)
components/Login.js
import { useState } from "react";
import loginService from "../services/login";
const LoginForm = ({ loggedInUser }) => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
console.clear();
const user = await loginService
.login({
username,
password,
})
.then((returnedUser) => {
console.log("handleSubmit", "running");
console.log("handleSubmit", returnedUser);
setUsername("");
setPassword("");
loggedInUser(returnedUser);
})
.catch(() => loggedInUser(null));
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Username</label>
<input
type="text"
name="Username"
value={username}
onChange={({ target }) => setUsername(target.value)}
/>
</div>
<div>
<label>Password</label>
<input
type="text"
name="Password"
value={password}
onChange={({ target }) => setPassword(target.value)}
/>
</div>
<button type="submit">Login</button>
</form>
);
};
export default LoginForm;
services/login.js
import axios from 'axios'
const baseUrl = '/api/login'
const login = async credentials => {
const response = await axios.post(baseUrl, credentials)
return response.data
}
export default { login }
service/blog.js
let token = null;
const setToken = (newToken) => {
token = `bearer ${newToken}`;
};
export default { setToken };

How to use useForm to validate input while using localStorage

I'm trying to validate a simple form with a single input just for practice. I also don't want the value that the user types in the input to disappear after page refresh, for that reason, I did a little bit of searching and found out about saving that data using localStorage. After trying to implement that for a while, I managed to do that, when I refresh the page, the value is still there. However, now, when I'm trying to validate the form using useForm from react-hook-form, It just doesn't work for some reason, when I try to use that same useForm logic with an input without using localStorage, It works just fine, but while trying to add localStorage functionality, then it doesn't. I hope I'm describing my problem at least okey, here's the code :
import React, {useEffect, useState } from "react";
import "./App.css"
import { useForm } from "react-hook-form";
const getForm = () => {
const storedValues = localStorage.getItem("form");
if(!storedValues) return {
name: "",
age: ""
}
return JSON.parse(storedValues);
}
function Home() {
const [values, setValues] = useState(getForm)
const {register, handleSubmit, watch} = useForm();
const handleChange = (e) => {
setValues((previousValues) => ({
...previousValues,
[e.target.name]: e.target.value,
}))
}
const onSubmit = async data => { console.log(data); };
useEffect(()=>{
localStorage.setItem("form", JSON.stringify(values))
}, [values])
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<input value={values.name} onChange={handleChange} name="name" placeholder="name" />
<input value={values.age} onChange={handleChange} name="age" placeholder="age"/>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default Home;
This code works fine since I'm not adding useForm register to the input, but if I do that, then It gets buggy, like this :
<input value={values.name} onChange={handleChange} name="name" placeholder="name" {...register("name")} />
The latest code only works If I remove the value atrribute from the input, but I can't do that, If I do, I can't use localStorage anymore.
Looking at the documentation, you had the syntax a little off with your register function. That function takes a second argument, which is an object of props, and that is where you want to define value, name and onChange.
Like this:
<input
placeholder="name"
{...register("name", {
onChange: handleChange,
name: "name",
value: values.name
})}
/>
Here is the full code I have working on a codesandbox. That's really all I changed, expect removing the watch import.
import React, { useEffect, useState } from "react";
import "./styles.css";
import { useForm } from "react-hook-form";
const getForm = () => {
const storedValues = localStorage.getItem("form");
if (!storedValues)
return {
name: "",
age: ""
};
return JSON.parse(storedValues);
};
function Home() {
const [values, setValues] = useState(getForm);
const { register, handleSubmit } = useForm();
const handleChange = (e) => {
setValues((previousValues) => ({
...previousValues,
[e.target.name]: e.target.value
}));
};
const onSubmit = async (data) => {
console.log(data);
};
useEffect(() => {
localStorage.setItem("form", JSON.stringify(values));
}, [values]);
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<input
placeholder="name"
{...register("name", {
onChange: handleChange,
name: "name",
value: values.name
})}
/>
<input
value={values.age}
onChange={handleChange}
name="age"
placeholder="age"
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default Home;

const { data } = useQuery problem: I want data to be object initially

I'm trying to implement a login function to my react app.
import React, { useState, useEffect } from 'react'
import { useQuery, useLazyQuery, useMutation } from "#apollo/client"
import { useForm } from "react-hook-form"
import { LOGIN } from '../queries/queries'
const Login = () => {
const [formValue, setFormValue] = useState({})
const { loading, error, data } = useQuery(LOGIN, {
variables: {
email: formValue.email,
password: formValue.password
}
})
const { register, handleSubmit } = useForm()
const onSubmit = (value) => {
setFormValue(value)
}
if (loading) return <p>loading</p>
return(
<>
<form onSubmit={handleSubmit(onSubmit)} >
<input
type="text"
name="email"
placeholder="E-mail"
ref={register}
/>
<input
type="password"
name="password"
placeholder="Password"
ref={register}
/>
<button type="submit">
Login
</button>
</form>
</>
)
}
When I code console.log(data.user) for example, error happens because user is not undefined.
I know I can get object from data if I code variables directly, but I want to get it after handleSubmit.
I think if I can make data object initially, error would not happen.
Then is there any way to do that?
try "data?.user" instead of "data.user" when referring to that object attribute
the question mark should disable the error if the object doesnt exist
update:
you can also try declaring data as an empty objec literal:
{ loading, error, data = {} }

Categories

Resources