How to do form post API in react? - reactjs

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

Related

Struggling with PUT request

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

How to show data using react

you are currently using react to replicate Spotify.
You are currently developing a search function and have successfully received a response.
I want to show this on the screen.
How do I solve this? Please help me.
const onClick = () => {
const inputSearchData = sessionStorage.getItem('inputData');
const inputTypeData = sessionStorage.getItem('inputType');
// console.log(inputTypeData)
axios({
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json",
"Content-Type": "application/json",
},
method: 'GET',
url: 'https://api.spotify.com/v1/search',
params: {
q: inputSearchData,
type: inputTypeData,
},
}).then((res) => {
console.log(res);
}).catch(err => {
console.log(err);
})
}
when you get your response from your axios request you need to store it inside react state.
access this inside the return statement of the component.
That will be something like that :
const SomeComponent = () => {
const [response, setResponse] = useState();
const onClick = async () => {
const inputSearchData = sessionStorage.getItem("inputData");
const inputTypeData = sessionStorage.getItem("inputType");
await axios({
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
"Content-Type": "application/json"
},
method: "GET",
url: "https://api.spotify.com/v1/search",
params: {
q: inputSearchData,
type: inputTypeData
}
})
.then((res) => {
setResponse(res);
})
.catch((err) => {
console.log(err);
});
};
return (
<div>
{/* Access your response state over here */}
{/* That will be something like that : */}
{response.map((item, index) => {
<div key={index}>
{item.somethingFromYourData}
</div>
})}
</div>
)
};

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?

displaying Flash message in react

My task is to display flash message("successfully created") on clicking the submit button.[On clicking the submit button , data will be stored in the server]I have run this command npm i react-flash-message.
<form onSubmit={this.handleSubmit}>
<input type="submit" value="Submit" />
</form>
handleSubmit function:
handleSubmit(event) {
fetch('url', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: this.state.name,
description: this.state.description
})
}).then(res => {
return res.json()
})
.then(data => console.log(data))
.then(() => {
window.location.reload(false)
/* return (
<div>
<FlashMessage duration={5000}>
<strong>I will disapper in 5 seconds!</strong>
</FlashMessage>
</div>
) */
})
/* window.flash('record has been created successfully!', 'success') */
.catch(error => console.log('ERROR from create component'))
}
}
I have commented the code I have tried to display flash message. But it is not working. Please someone help me to display the flash message.
According to react-flash-message page , you should include the FlashMessage in your render. So you may need to have a flag variable to set as true when you want to show the FlashMessage
Example:
in your render :
<form onSubmit={this.handleSubmit}>
<input type="submit" value="Submit" />
{ this.state.showMessage &&
<div>
<FlashMessage duration={5000}>
<strong>I will disappear in 5 seconds!</strong>
</FlashMessage>
</div>
}
</form>
handleSubmit function :
handleSubmit(event) {
this.setState({ showMessage: false });
fetch('url', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: this.state.name,
description: this.state.description
})
}).then(res => {
return res.json()
})
.then(data => console.log(data))
.then(() => {
this.setState({ showMessage: true });
})
/* window.flash('record has been created successfully!', 'success') */
.catch(error => console.log('ERROR from create component'))
}
}
main function if you are using class:
constructor(props) {
super(props);
this.state = {
showMessage: false
};
}
https://www.npmjs.com/package/react-flash-message
Easy peasy..
Whenever using onSubmit, dont forget to use event.preventDefault()..
And try using only one then block.
Now maintain a state variable, to set the status of the result. Once the result is fetched set the result status to true.
Render your FlashMessage component, when its true.
https://codesandbox.io/s/lucid-taussig-9x0o3

How to clear the input after posting the data through fetch and making the code execute successful

I'm new to react, have created a chat using reactjs. I'm using "POST" request through fetch to post new message for a particular conversation. My Objective is when i send a message, then it should clear the input but unable to clear the input after sending message. Need to write for error also.. Anyone can help me in this?
myCode:
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
handleSend = event => {
const { phonNo } = this.props.phonNo;
event.preventDefault();
console.log("phone : " + "+" + phonNo);
this.setState({ toPhoneno: phonNo });
console.log("phonefkjdk : " + "+" + this.state.toPhoneno);
const data = {
toPhoneno: "+" + this.state.toPhoneno,
body: this.state.body
};
fetch("/api/messages", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
})
.then(res => res.json())
.then(() => {});
};
render () {
return (
<div>
<input
className="sendMessage"
onChange={this.handleChange}
/>
<Button onClick={this.handleSend} className="sendBtn" icon>
<Icon name="send" color="blue" />
</Button>
</div>
);
}
Can anyone help me in this ? Thanks in advance
You can clear it end of the fetch Promise chain.
fetch("/api/messages", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
})
.then(res => res.json())
.then(() => {
this.setState({ sendMessage: "" })
});
input should be controlled and it should have a name.
render () {
return (
<div>
<input
className="sendMessage"
name="sendMessage"
value={this.state.sendMessage}
onChange={this.handleChange}
/>
<Button onClick={this.handleSend} className="sendBtn" icon>
<Icon name="send" color="blue" />
</Button>
</div>
);
}

Resources