I am trying to use axios.post (in TS) to get responses from server (using POST as GET) without sending any Data. The server sends back the Data but REACT cant handle the responses.
Here is the react component:
interface allComapnies {
comapniesData:CompanyData[];
}
function GetAllCompanies(props:allComapnies): JSX.Element {
const myURL = globals.urls.admin+"get_company/all";
const [comapniesData,setData] = useState([new CompanyData()]);
useEffect(()=>{axios.post(myURL).then((response)=>{
console.log(response.data);
setData(response.data);
}).catch(error=>{console.log(error)});
},[]);
return (
<div className="getAllCompanies">
{comapniesData.map(item=><OneCompany
key ={item.id}
id={item.id}
name={item.name}
email={item.email}
/>)}
</div>
);
}
export default GetAllCompanies;
The console message shows:
Error: Request failed with status code 302
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.onloadend (xhr.js:54)
The browser get the responses from the server:
[{id: 2, name: "company2", email: "hgfytj#fdgreg", password: "trjyjytk",…},…]
The function of the REST Post inside the Controller in the Server(SPRING):
#RestController
#RequestMapping("admin")
#CrossOrigin(origins = "localhost:3000", allowedHeaders = "*")
#RequiredArgsConstructor
public class AdminController extends ClientController {
private final AdminService adminService;
...
#PostMapping("get_company/all")
public ResponseEntity<?> getAllCompanies() {
return new ResponseEntity<>(adminService.getAllCompanies(), HttpStatus.FOUND);
}
...
}
I found the problem. It was that I sent http status number 302 as a send confirmation, instead of number 200.
This prevented the server from sending the desired information in response. I have now changed the status to 200 and the information is received even when sending "axios.post" with an empty request.
#PostMapping("get_company/all")
public ResponseEntity<?> getAllCompanies() {
return new ResponseEntity<>(adminService.getAllCompanies(), HttpStatus.OK);
}
Try GET method instead POST cause you are getting data from your DB and not sending it to.
Related
I'm writing a simple web with Rocket as backend and React as frontend.
The code snippet looks like this for login page
#[post("/login", data = "<data>")]
pub fn login(
conn: DbConn,
mut cookies: Cookies<'_>,
data: Form<LoginForm>,
) -> Result<JsonValue, NotFound<String>> {
let valid_account = match Account::find_by_email(&*conn, data.email.as_str()) {
Ok(account) => {
if account.password == data.password {
account
} else {
return Err(NotFound("Incorrect email or password!".to_string()));
}
}
Err(_) => return Err(NotFound("Incorrect email or password!".to_string())),
};
cookies.add_private(
Cookie::build(AUTH_COOKIE, valid_account.id.to_string())
.same_site(rocket::http::SameSite::Strict)
.finish(),
);
Ok(json!({
"email": valid_account.email,
"name": valid_account.name,
}))
}
Code for main.rs
fn main() {
rocket::ignite()
.mount("/", routes![
account::login::login,
],
)
.register(catchers![errors::unauthorized])
.attach(rocket_cors::CorsOptions::default().to_cors().unwrap())
.manage(establish_connection())
.launch();
}
and code for React when trying to send the post request
export const postForm = async (
pathUrl: string,
postInfo: { [name: string]: any }
) => {
let axiosConfig = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
},
};
try {
const response = await axios.post(
baseUrl + pathUrl,
querystringify.stringify(postInfo),
axiosConfig
);
return response.data as CurrentUser;
} catch (err) {
console.log(err);
return Promise.reject(err.response);
}
};
The code works fine it I enter the correct email and password.
However, it cannot capture the error message if I enter the wrong credentials.
Rocket log are the same between successful login and failure login which are
OPTIONS /login:
=> Error: No matching routes for OPTIONS /login.
=> Warning: Responding with 404 Not Found catcher.
=> CORS Fairing: Turned missing route OPTIONS /login into an OPTIONS pre-flight request
=> Response succeeded.
POST /login application/x-www-form-urlencoded:
=> Matched: POST /login (login)
=> Outcome: Success
=> Response succeeded.
and the error log in browser I captured was Error: "Request failed with status code 404" which was not the expected error message hard coded inside post function.
I believe it has something to do with Option or preflight processed inside Rocket which maybe in the purpose of security. But how can I suppress the system error and let my code to take over?
I have read previous SO post like state undefined: while sending post request from react app and GitHub issues like https://github.com/SergioBenitez/Rocket/issues/25. And still cannot find answer for my problem.
Thanks in advance!
Apparently I made several mistakes here due to unfamiliar with Rocket and React.
List here in case someone made the similar mistakes.
The 404 status code is from the first code snippets Result<JsonValue, NotFound<String>>. So if we write the return type as Result<JsonValue, Unauthorized<String>>, it would return 401 as unauthorized user.
Second, axios only receives json type and cannot parse string (correct me if I'm wrong). So we need to change the return type in server to Result<JsonValue, Unauthorized<JsonValue>>.
I'm building a React.js app with ASP.NET Core as backend following a tutorial course. I'm using Axios to handle HTTP requests, I tested the get, post, put requests working fine, but keep getting error during a del request. Here is the simplified function that produces the same error:
const handleDeleteActivityTest = () => {
Axios.delete('https://localhost:5001/api/activities/e2beb0eb-eaaa-49ee-92d8-daf472210456');
}
And the request prints the following error messages in the console:
DELETE https://localhost:5001/api/activities/e2beb0eb-eaaa-49ee-92d8-daf472210456 415
(Unsupported Media Type)
createError.js:16 Uncaught (in promise) Error: Request failed with status code 415
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:61)
But I tested in Postman, and the delete request works just fine and returns a 200 OK response, and I can see in the database that the entry is deleted:
Postman DELETE response
I would really appreciate if someone can educate me what's going on here. Thank you and stay safe & happy.
EDIT ----------------------------------
Here is the backend code that handles the HTTP request. It is divided into two parts-- 1.) controller that receives the HTTP request and 2.) MediatR class that handles it:
1.)
namespace API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ActivitiesController : ControllerBase
{
private readonly IMediator _mediator;
public ActivitiesController(IMediator mediator)
{
_mediator = mediator;
}
[HttpDelete("{id}")]
public async Task<ActionResult<Unit>> Delete(Guid id, Delete.Command command)
{
command.Id = id;
return await _mediator.Send(command);
}
}
}
2.)
namespace Application.Activities
{
public class Delete
{
public class Command : IRequest
{
public Guid Id { get; set; }
}
public class Handler : IRequestHandler<Command>
{
private readonly DataContext _context;
public Handler(DataContext context)
{
_context = context;
}
public async Task<Unit> Handle(Command request, CancellationToken cancellationToken)
{
var activity = await _context.Activities.FindAsync(request.Id);
if (activity == null)
throw new Exception("Could not find activity");
_context.Remove(activity);
var success = await _context.SaveChangesAsync() > 0;
if (success) return Unit.Value;
throw new Exception("Problem saving changes");
}
}
}
}
I found that the HttpDelete method in the controller receives id as a Guid, but in the React app id is typed as string, so I changed the type to string in the controller and MediatR class, but same http error 415.
Axios doesn't send a content-type on a delete call. It looks like ASP.net core wants a content-type.
As a workaround you could just add a body to the delete call then Axios will add a content-type and that should do the trick.
const handleDeleteActivityTest = () => {
Axios.delete('https://localhost:5001/api/activities/e2beb0eb-eaaa-49ee-92d8-daf472210456', {
data: {foo: 'bar'}
});
}
I am working on Angular2 web project, in my ts class I have an object :
Object: any= {
"first":null,
"second":null,
"third": null,
}
I want to send the object in http.post request body. I tried the next code, but it doesnot work;
method() {
const url='/pathname/';
return this.http.post(url, this.Object).pipe(map((data:any)=>data));
}
I got an error in console:
error : HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: "OK",url: "http://localhost:8080/path", ok: false,..}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for
http://localhost:8080/path 400 OK"
name: "HttpErrorResponse"
ok: false
status: 400
statusText: "OK"
url: "http://localhost:8080/path"
Can you explain me how to send typescript object in post request body ? Thank you in advance
You need to subscribe to the post observable returned by method function. It is done like this.
this.method().subscribe(
res => {
// Handle success response here
},
err => {
// Handle error response here
}
);
you should subscribe the post method because this method of http class returns a observable.
you can rewrite your code as:-
method() {
const url='/pathname/';
return this.http.post(url, this.Object).subscribe( resp=> {
const data = resp; // response you get from serve
}, error => {
console.log(error); //error you get from server
});
}
you are getting the 400 bad request error, the payload keys are mis matching with the middle wear. please suggest pass the correct params into Request object.
I am using React.js in macOS and when I try to call axios.get, I get Network Error. I read many other cases like mine who were using React Native and the answer to them was adding settings to allow them to use http in mac instead of https, but that setting can not be used in react js.
Any advice would be appreciated.
Error: Network Error
at createError (createError.js:17)
at XMLHttpRequest.handleError (xhr.js:87)
My code is like this:
try {
const Response = await axios.get(http://xxxxx/WebServiceTest/service.svc?wsdl/GetItems, {
params: {
Number: "100",
Id: "101",
userName: "11",
credential: "Test"
}
});
console.log("http response = " + Response.data);
} catch (ex) {
console.log("error.status:", ex);
}
Change your await to a promise, even if you put await the axios function will work asynchronously.
async functionName() {
let response = () => {
return new Promise(function(resolve, reject) {
fetch('http://xxxxx/WebServiceTest/service.svc?wsdl/GetItems', {
params: {
Number: "100",
Id: "101",
userName: "11",
credential: "Test"
}
}).then(response => {
resolve(response);
});
});
};
let responseData = await response();
console.log(responseData.data);
}
You can simply make the following changes in your
axios.create({baseURL:" "});
make it into
const instance = axios.create(
{
baseURL: "",
withCredentials: false,
headers: {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
})
In your case try adding the above wherever you must have created instance of your axios.If you are using default axios then consider creating custom instance following the above code.
I have found the solution in spring boot by using #CrossOrigin annotation.
#RestController
#CrossOrigin
#RequestMapping("/cus")
public class CusController{
#Autowired
CustomerService cus_service=null;
#PostMapping("/save")
public Customer saveCustomer(#RequestBody Customer customer)
{
if(customer!=null)
return cus_service.saveCustomer(customer);
else
throw new DataNotFoundException("Data Not Available For Customer");
}
}
You can use axios method in reactjs using some commands on server side code to get rid of cors policy error
i have used these commands on my server side code which is in php
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: *');
header('Access-Control-Max-Age: 1728000');
header("Content-Length: 0");
header("Content-Type: text/plain");
remember: add these lines immediately starting session
We have to allow CORS, placing Access-Control-Allow-Origin:* in header of request may not work. Install a google extension which enables a CORS request.
Make sure the credentials you provide in the request are valid.
if you are passing request to the virtual homestead server, make sure the machine has been provisioned. If you are using vagrant try vagrant up --provision this will make the localhost connect to db of the homestead.
Try changing the content type of the header. header:{ 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8;application/json' }
this point is very important.
I'm currently trying to POST data to my aws lambda functions triggered by aws api-gateway using the aws-amplify react lib.
Here is the code :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(console.log(err))
In the main case, everything is OK.
But my lambda function is design to validate the input data and return a status code 400 with a returned payload looking like that :
{
"errors": [
{
"field": "title",
"message": "This field is required"
}
]
}
I would like to catch those errors in order to display them in the frontend but aws-amplify seems to have an undocumented behavior.
By default, status code 400 returned are throw with a default error message :
Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
Is there a way to get the returned payload instead of this magical error?
It turns out that under the hood, aws-amplifyuse Axios to make http calls.
When using Axios, you have to console.log(error.response): https://github.com/axios/axios/issues/960
Here is the fix I've made :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(error => console.log(error.response.data))
A Pull Request on the aws-amplify documentation is open : https://github.com/aws/aws-amplify/pull/633
I also faced the similar issues, It showed the default error message "Request failed with status code 400", instead of the message that is returned from API.
I logged the Error object and it did not show the response attribute in it. But we do have response attribute. I tried logging the Error.response and it did contain the response sent from the API.
Just figured out this by going through the 'Cancel API requests' Amplify docs.
From what I can see this is the contents of the error object returned by the API call:
Heres what I am doing to just print out the error, obviously you would do a lot more here but its a good start.
async uploadUser(state, payload) {
const promise = API.graphql({
query: createUser,
variables: { input: payload },
});
try {
await promise;
} catch (error) {
// Print out the actual error given back to us.
console.log(error.errors[0].message);
// If the error is because the request was cancelled we can confirm here.
if (API.isCancel(error)) {
// handle user cancellation logic.
console.log(error.message);
}
}
Hope that helps 😃