Struggling with PUT request - reactjs

I'm on React for 2 months, and still struggling with CRUD operations such as EDIT.
I've been trying couple different ways, but every time I send nothing to my API.
I do not manage to grab the information correctly in order to push it to the server.
The route is working with Postman, there are no issues there, it's only React and me ^^.
I would be grateful if someone could read my code and tell me where the problem might come from, thanks !
1st try
const usernamelEl = React.useRef(null)
const timezoneEl = React.useRef(null)
const handleEditProfile = async () => {
const creds = {
user: {
username: usernameEl.current.value,
timezone: timezoneEl.current.value
}
};
const config = {
method: 'PUT',
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"Authorization": `Bearer ${Cookies.get('token')}`
},
body: JSON.stringify(creds)
};
const res = await fetch(`${process.env.REACT_APP_API_URL}api/users/${id}`, config);
const user = await res.json();
console.log(user)
}
return (
<form onSubmit={handleEditProfile} className="form">
<div className="input-group">
<label htmlFor="username">username</label>
<input type="text" id="username" ref={usernameEl}/>
</div>
<div className="input-group">
<label htmlFor="timezone">timezone</label>
<input type="text" id="timezone" ref={timezoneEl}/>
</div>
<div className="input-group">
<SubmitButtonComponent type="submit">
Submit
</SubmitButtonComponent>
</div>
</form>
)
2nd try
const [usernameEl, setUsernameEl] = useState('')
const [timezoneEl, setTimezoneEl] = useState('')
const handleChangeUsername = e => {
setUsernameEl(e.target.value)
}
const handleChangeTimezone= e => {
setTimezoneEl(e.target.value)
}
const handleEditProfile = async (e) => {
const creds = {
user: {
username: usernameEl,
timezone: timezoneEl
}
};
const config = {
method: 'PUT',
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"Authorization": `Bearer ${Cookies.get('token')}`
},
body: JSON.stringify(creds)
};
const res = await fetch(`${process.env.REACT_APP_API_URL}api/users/${id}`, config);
const data = await res.json();
console.log(data)
try {
setUsernameEl('')
setTimezoneEl('')
}
catch(err) {
console.log(err)
}
}
return (
<form className="form" onSubmit={handleEditProfile}>
<div className="input-group">
<label htmlFor="username">username</label>
<input type="text" id="username" onChange={handleChangeUsername}/>
</div>
<div className="input-group">
<label htmlFor="timezone">timezone</label>
<input type="text" id="timezone" onChange={handleChangeTimezone}/>
</div>
<SubmitButtonComponent type="submit">
Submit
</SubmitButtonComponent>
</form>
if I ever try to pass a value
const handleEditProfile = async (e) => {
e.preventDefault();
[..]
onSubmit={(e)=>handleEditProfile(e.target.value)}>
or
onSubmit={handleEditProfile(e)>
then I get this error

Related

Can't send files using Redux Form

I'm creating a webpage for me and I'm working with Redux/Redux Form. My backend is working fine, but I can't figure out how to work on my front-end. I'm not using any library to fetch the image in my front, I just copy and pasted a FieldFileInput and it's working fine.
Here is my PostForm.tsx:
renderInput = ({input, label, meta}: {input: any, label: any, meta: any}) => {
const className = `field ${meta.error && meta.touched} ? 'error' : ''`;
return (
<div className={className}>
<label>{label}</label>
<div className="input-group input-group-lg">
<input className="form-control"{...input} autoComplete="off"/>
</div>
{this.renderError(meta)}
</div>
)
};
onSubmit = (formValues: any) => {
//#ts-ignore
this.props.onSubmit(formValues)
};
render() {
return (
<form
onSubmit={ this.props.handleSubmit(this.onSubmit)}
className="ui form error"
>
<div className="create-post-field-two">
<Field
name="title"
component={this.renderInput}
label="Enter Title"
/>
</div>
<div className="create-post-field-two">
<Field
name="body"
component={this.renderInput}
label="Enter Description"
/>
</div>
<div className="create-post-field-two">
<Field
name="imageUrl"
component={FieldFileInput}
label="Enter Image"
/>
</div>
<div className="postButton">
<button className="btn btn-outline-secondary">Submit</button>
</div>
</form>
)
}
}
In this page I'm certain that everything works correctly, because I receive all data in my Action.
Here is my Redux Action
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
// 'Content-Type': 'multipart/form-data',
authorization: `Bearer ${token}`,
};
let formData = new FormData();
formData.append('imageUrl', formValues.imageUrl);
try {
const response = await AlleSys.post('/posts', {...formValues, image: formData}, {headers})
dispatch({type: CREATE_POST, payload: response.data})
history.push('/')
}catch (err) {
console.log("ERROR: Couldn't post for identified user");
}
};
If I uncomment the Content-Type I receive the error Error: Multipart: Boundary not found
in my Back-End.
Here Is a screenshot of my request using insomnia.
I'm stuck on this for days and I can't figure out how to achieve the file upload in the front-end. Please don't mind the typings, I'll correct later.
I used bodyFormData.append to my form fields in the Redux Action and worked like a charm.
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
authorization: `Bearer ${token}`,
Accept: 'application/json',
};
const { title, body, image } = formValues;
const bodyFormData = new FormData();
bodyFormData.append('title', title);
bodyFormData.append('body', body);
bodyFormData.append('image', image);
try {
const response = await AlleSys.post('/posts', bodyFormData, {headers})
console.log(response)
dispatch({type: CREATE_POST, payload: response.data})
history.push('/')

How to do form post API in react?

I would like to add data to my database through the API url, with a form. But it's not really working. I'm kind of struggling to make it work. When I click on 'add' I check the array but nothing new is being added. I think i'm doing something wrong in the body variable. But not sure. How can i get the values from the form into the url API?
Here is my code:
export function AlbumForm(props) {
const [PostId, setPostId] = useState(0);
const {register, handleSubmit, errors, control} = useForm({
defaultValues: props.album
? props.album
: {
name: "",
artist: "",
imageUrl: "",
},
});
const useCreateAlbum =((data) => {
console.log(data);
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: data,
mode: 'cors'
};
fetch(process.env.REACT_APP_API_URL, requestOptions)
.then(response => response.json())
.then(data => setPostId(data.id));
});
return (
<div className="AlbumForm">
<h2>Album Form</h2>
<form onSubmit={handleSubmit(useCreateAlbum)}>
<input type="text" {...register("name")} placeholder="Name" name="name"/>
<input type="text" {...register("artist")} placeholder="Artist" name="artist" />
<input type="text" {...register("imageUrl")} placeholder="ImageUrl" name="imageUrl"/>
<button type="submit">{props.submitbutton}</button>
</form>
</div>
);
}
never mind I solved it. I just had to do this:
const useCreateAlbum =((data) => {
console.log(data);
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),/////here is the change
mode: 'cors'
};
fetch(process.env.REACT_APP_API_URL, requestOptions)
.then(response => response.json())
.then(data => setPostId(data.id));
});

Rect Post request

I am creating project in React /Django Rest Framework and I want to send Post request. My problem is that I am always sending string and I should send list of int.
My component look like this
const NewLecture = (props) => {
const[ lecture, setLecture] = useState({
title:'',
programs: [],
})
const dispatch = useDispatch()
const history = useHistory()
// console.log('this is history:', history)
const program_id = props.match.params.id;
//event handlers
const newLectureHandler = (event) => {
const{name, value}= event.target
setLecture({
...lecture,
[name]:value
})
};
useEffect(() => {
console.log('mounting in NewLecture');
dispatch(LecturesActions())
dispatch(GetPrograms())
}, [])
const handleSubmit = e =>{
e.preventDefault()
props.close()
dispatch(sendLecture(lecture, program_id, history))
}
const stringtoArray = (arg)=> {
console.log('this is arg', [arg]);
return [arg]
}
return (
<NewGradeStyled>
<div className="new-grade-style">
<h1>Create New Lecture</h1>
<form >
<div className="form-grade">
<label htmlFor="title">Lecture Name</label>
<input type="text" name="title" onChange={newLectureHandler}/>
</div>
<div className="form-grade">
<label htmlFor="programs">Program</label>
{/* <input type="number" name="programs" onChange={newLectureHandler}/> */}
<select name="programs" onChange={newLectureHandler}>
<option > </option>
{props.data ? <option value={props.data.id}>{props.data.name}</option> : ''}
</select>
</div>
<div className="btn-group">
<button className="save" onClick={handleSubmit}>Save</button>
<button onClick={props.close}>Cancle</button>
</div>
</form>
</div>
</NewGradeStyled>
)
}
export default withRouter(NewLecture)
and this is my action
export const sendLecture = (lecture) => (dispatch, getState) => {
const{title, programs} = lecture
const token = getState().token
const config = {
body: JSON.stringify(lecture),
method: "POST",
headers: new Headers({
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}),
body: JSON.stringify({title, programs})
};
fetch(`${baseUrl}/backend/api/lectures/new/`, config)
.then((res) => res.json())
.then((data)=>{
console.log('Post lecture action', data)
dispatch({type: 'GET_LECTURE_DATA', payload: data})
});
}
I expect to get this from JSON
{
"title":"some string"
"programs":[1]
}
reducer
const initialState = {
lecture_data:[],
}
export const authReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_LECTURE_DATA": {
const lecture_data = action.payload;
return { ...state, lecture_data };
}
default:
return state;
}
}
If I send it as input type= "number" result is always the same I get error "Expected a list of items but got type "str"."
I don´t kow how I should change it. Do you have any Ideas?
In this part:
const config = {
body: JSON.stringify(lecture),
method: "POST",
headers: new Headers({
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}),
body: JSON.stringify({ title, programs })
};
you set the body property twice. Is that intentional?
You write the api expects a list. Did you mean to pass this body: JSON.stringify( [title, programs ]) Although that would send an array of objects of which the first item is title, and the second is programs. Can you clarify what the API expects? And what the structure of title and programs looks like?

React - Post Request does not work on mobile

I'm trying to submit some simple data to my server. Everything works fine - on my desktop. When i try on my mobile (same network) it does not work. The page just refreshes but the POST request fails (not sure if it fails because i can't open a console on my mobile). It seems like the page refreshes before it actually gets to the fetch command but i'm not sure and not sure how to troubleshoot because it is working fine on my desktop. Please help! Thanks :)
const onSubmit = (event) => {
const data = {
price: price,
gallons: gallons,
miles: miles,
notes: notes,
source: params.car_source,
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
};
fetch(`${process.env.REACT_APP_API_BASE_URL}/consumption/`, options);
};
This will work! Try this out, Just added event.preventDefault() in handleSubmit function.
I follow this link for Debugging in mobile.
import React, { useState } from 'react';
function NameForm() {
const [name, setName] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
const data = {
price,
gallons,
miles,
notes,
source: params.car_source,
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
};
fetch(`${process.env.REACT_APP_API_BASE_URL}/consumption/`, options);
};
const handleChange = (event) => {
setName(event.target.value);
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
export default NameForm;

how to get input value with typescript(put request )

I want to get input value and put them in json
but I don't know how to get input value in this case
if I tried document.querySelector("todo-text").value
It turns out to error.
const NewTodo: React.FC<NewTodoProps> = (props) => {
/* const textInputRef = useRef<HTMLInputElement>(null); */
const formData = new FormData();
const photos = document.querySelector('input[type="text"][multiple]');
const data = {
word: document.querySelector<HTMLInputElement>("todo-text").value,
meaning: document.getElementById("todo-meaning"),
};
const handleSubmit = async () => {
const body = JSON.stringify(data);
debugger;
const response = await fetch("https://localhost:5001/api/vocas", {
method: "POST", // *GET, POST, PUT, DELETE, etc.
//mode: "cors", // no-cors, *cors, same-origin
//cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
//credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
Accept: "*/*",
},
//redirect: "follow", // manual, *follow, error
//referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: body, // 本文のデータ型は "Content-Type" ヘッダーと一致する必要があります
});
debugger;
const result = await response.json();
console.log(result);
return;
};
return (
<form onSubmit={handleSubmit}>
<div className="form-control">
<label htmlFor="todo-text">単語:</label>
<input type="text" id="todo-text" />
<br />
<label htmlFor="todo-meaning">意味:</label>
<input type="text" id="todo-meaning" />
</div>
<button type="submit">追加</button>
</form>
);
};
in this case, how to get input value??
We need to use useState to get the capture the userinput
import {useState} from 'react';
const[toDoText,setToDoText] = useState("");
in input field add a onChange Event
const handleInput = (event : React.ChangeEvent<HTMLInputElement>) => {
let target = event.target;
setToDoText((currentState) => {
return target.value;
})
}
<input type="text" id="todo-text" onChange={handleInput} />

Resources