React axios post request does not send the data - reactjs

I am using react for my app. I am learning post request. I found one dummy api site Mocky where I can test my post request. This is my api link .For post request I used axios. I don't know how the Mocky api works. I made post request. when I console log the input values I can the value.But when I console log the response it seems like it does not get the data. I don't see any where I am making mistake.
Here is my code:
import React, { useState } from 'react';
import { API_URLS } from '../utilities';
import axios from "axios";
export default function CreateAccount() {
const [state, setState] = useState({
"email": ``,
"password": ``,
"loading": false,
"error": ``
});
const onChangeStudent = (e) => {
setState({
...state,
[e.target.id]: e.target.value
});
};
const onSubmit = async (e) => {
e.preventDefault();
console.log(state);
const url = `https://run.mocky.io/v3/15c2b7ec-9f31-4a18-ae60-a7f41e1f39b2`;
const obj = {
"email": state.email,
"password": state.password
};
console.log(obj.email); //I can see the input value
console.log(obj.password);//I can see the input value
axios
.post(url, obj)
.then((res) => {
console.log(res.data); // it does not show the data
console.log(res);
})
.catch((error) => {
setState({
...state,
"error": error
});
});
};
return (
<div>
<form onSubmit={onSubmit}>
<input
type="text"
value={state.name}
onChange={onChangeStudent}
id="email"
required
/>
<input
type="password"
value={state.password}
onChange={onChangeStudent}
id="password"
required
/>
<button
className="btn waves-effect blue lighten-1"
type="submit"
name="action"
disabled={state.loading}
>
{state.loading ? `loading...` : `save`}
</button>
</form>
</div>
);
}

Hi can't seem to find anything wrong with what you are doing.
I tested the below and it worked for me. Try to change from .then to await. Hope this solves your problem. Check in your network tab if your request is successful and if you are sending the body.
try {
const response = await axios.post('https://run.mocky.io/v3/4b95050f-2bcc-4c78-b86e-6cac09372dce', data);
console.log("Response", response);
} catch(e) {
console.error(e);
}

Related

FormData not working with Axios Post request - MERN react Js

I've been trying to make a post request to my server(Node Js+Mongodb which runs on localhost too). Axios.post works properly on the client code, however when i try to use formData it doesn't. I can't seem to find any reason why it's not working.
It leaves no error on the console(which makes it more frustrating).
Here is the client code:
someone pls point me to what I might be doing wrong.
import React, { useState } from 'react'
import Axios from 'axios'
export default function InputData() {
const [inputName, setInputName] = useState("")
const [inputAge, setInputAge] = useState(0)
const [inputEmail, setInputEmail] = useState("")
const [userImage, setUserImage] = useState("")
const [info,setInfo] = useState("")
var bodyFormData = new FormData();
bodyFormData.append('name', inputName);
bodyFormData.append('age', inputAge);
bodyFormData.append("email", inputEmail)
const createUser = () => {
Axios.post("http://localhost:3008/createUser",
bodyFormData , { headers: { 'Content-Type': 'multipart/form-data' } }).then(function (response) {
//handle success
console.log(response);
}).catch(function (response) {
//handle error
console.log(response);
});
}
return (
<div>
<form onSubmit={createUser} encType="multipart/form-data">
<div>
<input type="text" placeholder='enter name' value={inputName} width={400} onChange={(e) => setInputName(e.target.value)} /><br/>
<input type="number" placeholder='enter age' width={400} value={inputAge} onChange={(e) => setInputAge(e.target.value)} /><br/>
<input type="email" placeholder='enter e-mail' width={400} value={inputEmail} onChange={(e) => setInputEmail(e.target.value)} /><br />
<button>Submit</button>
</div>
</form>
</div>
)
}
axios: "^0.27.2",
react: "^18.2.0"
Couple of points:
You're probably not seeing any errors (output) in the console because you're submitting the form. You can change your onSubmit handler to include preventDefault:
const createUser = (e) => {
Axios.post("http://localhost:3000/createUser", bodyFormData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(console.log)
.catch(console.error);
e.preventDefault();
}
You can also keep it as is and see the previous output by persisting the logs of your browse across requests, in Firefox this checkbox:
You should add method=post to your form
I think you will receive all the data from the event [createUser method] on submitting the form, Try removing the header If you still have problem try as below, If you still have the problem check the server side Post method Params
let data = { name: inputName, age: inputAge, email: inputEmail }
Axios.post("http://localhost:3008/createUser",data )
.then(function (response) { console.log(response); })
.catch(function (response) { console.log(response); });

Apollo `useMutation()` stuck loading inside Next.js component

The following form component in Next.js submits without errors but never completes the mutation. Instead it get's stuck in the loading state.
import React, { useState } from "react";
import { gql, useMutation } from "#apollo/client";
import { ApolloClient, InMemoryCache } from "#apollo/client";
const client = new ApolloClient({
ssrMode: true,
uri: process.env.API_URL,
cache: new InMemoryCache(),
});
const CREATE_COMMENT = gql`
mutation CreateComment(
$username: String!
$comment: String!
) {
createComment(
data: { username: $username, comment: $comment }
) {
id
username
comment
}
}
`;
export default function SocialForm() {
const [commentName, updateCommentName] = useState("");
const [commentDescription, updateCommentDescription] = useState("");
const [createComment, { data, error, loading }] = useMutation(
CREATE_COMMENT,
{ client }
);
const handleFormSubmit = async () => {
await createComment({
variables: {
name: commentName,
comment: commentDescription
},
});
};
if (loading) return "loading...";
if (error) return <p>error text :(</p>;
return (
<>
<form
onSubmit={async (e) => {
e.preventDefault();
await handleFormSubmit();
}}
className="social-form"
>
<input
required
onChange={(e) => updateCommentName(e.target.value)}
type="text"
placeholder="Full Name"
className=""
/>
<textarea
required
maxLength="280"
onChange={(e) => updateCommentDescription(e.target.value)}
className="w-full"
name="comment"
rows="5"
placeholder="Leave your thoughts and images at the moment"
/>
</form>
</>
);
}
Also the server side mutation with this exact same schema runs correctly inside Apollo playground and I'm using Keystone.js to auto generate the schema.
There's an error in your example:
const handleFormSubmit = async () => {
await createComment({
variables: {
name: commentName, // <-- Shouldn't this be `username: commentName,`?
comment: commentDescription
},
});
};
Otherwise, when you say the form "submits without errors but never completes", I assume you mean, from your browser? Can you see the GraphQL request being made in the browsers developer tools? I don't know which one you're in but there should be a way to see the requests being made and their responses. If the GraphQL server is returning an error, you'll see it there.
Also, what is Keystone logging on the command line during all this? If you add some console.log() statements to your custom mutation, do they get called?

Unable to render output of an API call made from a text field unto the UI

pls am currently building a simple UI using react on codesandbox. I just want the user to be able to enter an API end point in a text field and have the output(response data) rendered on a text area. Below is my codesandbox project link:
https://codesandbox.io/s/dry-surf-6ygc5?file=/src/components/PostList.jsx. Your input will be highly appreciated!
It seems like your missed to the target value of input text in the OnChange event for the Input. Please see the below code if that helps.
<input
name="inputApi"
onChange={(e) => this.setState({ apiText: e.target.value })}
type="text"
/>
I have removed few of your code. Also i didn't do other functionality like error handling. Please add a try catch block to Async block
submitHandler = async (e) => {
e.preventDefault();
try {
const resp = await axios.get(
`https://jsonplaceholder.typicode.com/${this.state.apiText}`
);
// console.log(resp.data);
this.setState({ posts: resp.data });
} catch (error) {
this.setState({ errorMsg: error.message });
}
};
Full code is here below.
import React, { Component } from "react";
import axios from "axios"; //for making API calls
class PostList extends Component {
constructor(props) {
super(props);
/**
* the lines below are unneccessary
* as the functions are arrow functions
* and require no binding
* value={this.state.api}
*/
this.state = {
posts: [],
errorMsg: "",
api: {},
apiText: ""
};
} //end of constructor
submitHandler = async (e) => {
e.preventDefault();
try {
const resp = await axios.get(
`https://jsonplaceholder.typicode.com/${this.state.apiText}`
);
// console.log(resp.data);
this.setState({ posts: resp.data });
} catch (error) {
this.setState({ errorMsg: error.message });
}
};
render() {
const { posts, errorMsg } = this.state; //destructure the state object
//console.log(res.data);
return (
<div>
<form onSubmit={this.submitHandler}>
<input
name="inputApi"
onChange={(e) => this.setState({ apiText: e.target.value })}
type="text"
/>
<input type="submit" />
</form>
List of Posts: {posts.length}
{posts.length ? (
<div>
<textarea value={this.state.posts[0].title} readOnly />
</div>
) : null}
{errorMsg ? <div>{errorMsg}</div> : null}
</div>
); //endOfReturn
} //endOfRender
} //endOfPostList
export default PostList;
/**posts.map((post) => <div key={post.id}>{post.title}</div>)*/
You have a small error getting the value in your submitHandler.
Instead of the user input value, you pass the string "e.target.value", which is not true.
const resp = axios.get("e.target.value");
Use it like this instead
const inputLink = e.target[0].value;
const resp = axios.get(inputLink);
It also makes no sense to store the result of calling the axios.get function in the component state.
Immediately after the call, you can use then and catch on the result of calling axios.get
axios
.get(inputLink)
.then((res) => {
this.setState({ posts: res.data });
})
.catch((error) => {
this.setState({
errorMsg: "error retrieving data"
});
});
Thus, a minimal working component will look something like this.

React-gatsby login authentioncation failed

I am using Gatsby for my app. I have created one api from Mock api. My api looks like this. I have made one post-request for login, when user will put his/her email and password, if it does not match then it will alert "failed login" or if it is success it will alert ("successfully login") and navigate to successful page. But what ever email and password I am putting it always shows me I login successfully which is wrong logic. The email should be like my api's email: alak#gmail.com" and password: test123 . I think my logic right but still I am making the mistake. I share my code in Codesandbox.
PS: Codesandbox is based on react. but logic is same as my below code
Here is my code:
import React, { ReactElement, useState } from 'react';
import { PageProps, navigate } from 'gatsby';
import styled from 'styled-components';
import MainTemplate from '../templates/index';
import { TextInput } from '../components/textInput';
import { Button } from '../components/buttons';
import { API_URLS } from '../utilities';
interface Props extends PageProps {
}
export default function SignIn({ }: Props): ReactElement {
const [state, setState] = useState({
"email": ``,
"password": ``,
"loading": false
});
const { loading } = state;
const signInValue = (e) => {
setState({
...state,
[e.target.id]: e.target.value
});
};
const onSubmit = async (e) => {
e.preventDefault();
console.log(state);
setState({
"loading": true,
...state
});
const response = await fetch(`https://run.mocky.io/v3/beec46b8-8536-4cb1-9304-48e96d341461`, {
"method": `POST`,
"headers": {
"Accept": `application/json`,
'Content-Type': `application/json`
},
"body": { state }
});
if (response.ok) {
alert(`you have suceefully login`);
navigate(`/success`, { "state": { email } });
} else {
alert(`login failed`);
}
};
return (
<MainTemplate>
<TextInput
type="text"
value={state.email}
onChange={signInValue}
id="email"
required
/>
<TextInput
type="password"
value={state.password}
onChange={signInValue}
id="password"
required
/>
<Button
type="submit"
name="action"
onClick={onSubmit}
disabled={loading}
> {loading ? `loading...` : `save`}
</Button>
</MainTemplate>
);
}
According to the fetch specification:
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
So your api might be returning an error but response.ok might still be true. You should check response.status !== 200 instead.
Update: works as shown below based on your sandbox:

Redux-form to pass data by a POST request.

I have to update my user's profile that has 5 fields name, bio address, image, and gender. I have created perfectly working API on Django that uses auth Knox token for authentication.
I have stored the auth token during login in the state. Of which the reducer looks like this:
case 'LOGIN_SUCCESSFUL':
case 'REGISTRATION_SUCCESSFUL':
localStorage.setItem("token", action.data.token);
return {...state, ...action.data, isAuthenticated: true, isLoading: false, errors: null};
I can access the token later on like this:
let headers = {"Content-Type": "application/json"};
let {token} = getState().auth;
if (token) {
headers["Authorization"] = `Token ${token}`;
}
My question is:
How can I make a form that takes this token as a header and makes a post request? What will be the reducers and what will be the actions?
class Profile extends Component {
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleSubmit(e) {
e.preventDefault()
console.log(this.props.Name)
}
change = e => {
console.log(e.target.name)
values.push(e.target.value)
[e.target.name]: e.target.value
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<label htmlFor="Name">Name</label>
<input name="Name" onChange={e => this.change(e)} component="input" type="text" />
</div>
<div>
<label htmlFor="Bio">Bio</label>
<input name="Bio" component="input" onChange={e => this.change(e)} type="text" />
</div>
<div>
<label htmlFor="Address">Address</label>
<input name="Address" component="input" onChange={e => this.change(e)} type="text" />
</div>
<button type="submit">Submit</button>
</form>
)
}
}
const mapStateToProps = (state) => {
return {
profile: state.user,
}
}
const mapDiapatchToProps = (dispatch) => {
return {
updateprofile: (values) => dispatch(updateprofile(values))
}
}
export default connect(mapStateToProps, mapDiapatchToProps)(Profile);
I tried this but I got confused how to send values to action?
Or Should I have to use redux-form?
I want to make a put request on this API: api/update/profile/${id}
Please help me out.
You need to use an external library to make a HTTP call, like Axios.
In your action file you need to create the function updateProfile. Inside this function you need to make the HTTP call using Axios, or wathever you want. With axios your function will be something like this:
function updateProfile() {
return (dispatch) => {
axios({
method:'get',
url:'[YOUR API ADDRESS]',
headers: {Authorization: '[YOUR TOKEN]'},
data: {
name: 'bruce',
lastName: 'bane'
}
}).then(function(response) {
dispatch({
type: UPDATE_PROFILE,
payload: response
});
});
return null
}
}
In youe Profile component you need to change the mapDispatchToProps function to call the updateProfile function from the action file, like this:
const mapDispatchToProps = (dispatch) => {
return {
updateprofile: (values) => dispatch(profileActions.updateprofile(values))
}
}
Note: I didn't tested this code, but it will be something close to this. Hope it could help.

Resources