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.
Related
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.
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 am new to reactjs and I am stuck in one problem. I am calling an Update API which is of PUT type. I use the fetch function to call the API in reactjs and I check the response of the API. If Response is 200 OK, then I return the response.json() and then check whether the json object has error in it or not. If it has error, then I print the error else I update it.
But when there is no Error present in the response, then I get a syntax-error in return response.json() statement and If there is actually a Error present in the response then there is no syntax-error shown. So is there a method to check whether the response is empty or not so that accordingly I can return response.json().
I have tried by putting a condition as if(response.json() != '') but it shows error in response.json() statement.
fetch( API + name , {
method: 'PUT',
headers: {
'Accept' : 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
},
body: JSON.stringify({
name: name,
description: updateDesc
}),
}).then(function(response) {
if(response.status == '200'){
flag=true;
return response.json();
}
else {
flag=false
}
})
.then(json => {
if(flag)
{
if(json.Error != "")
{
that.createNotification('error','update');
}
else {
this.createNotification('success','update');
}
}
});
Unhandled Rejection (SyntaxError): Unexpected end of JSON input
There are multiple issues with this imo:
The callback should be refactored to avoid the use of the flag variable. The code in the function supplied to handlers like then, catch and finally of promises is executed asynchronously. Therefore you cannot be sure / (should not assume) when this value will be assigned and in which state your context is at that time.
.then(json => { if there is an error this will actually use the promise returned by fetch aka response and not the promise returned by response.json() (Currently return response.json() is only executed in the success case)
Note that this happens (currently works in the error case) because you can chain promises. You can find more info and examples about this here
I would refactor the handling of the fetch promise like this:
You can shorten the following example and avoid assigning the promises, but it makes the example better readable
More information about the response object
const fetchPromise = fetch(<your params>);
fetchPromise.then(response => {
if (response.ok()){
//Your request was successful
const jsonPromise = response.json();
jsonPromise.then(data => {
console.log("Successful request, parsed json body", data);
}).catch(error => {
//error handling for json parsing errors (empty body etc.)
console.log("Successful request, Could not parse body as json", error);
})
} else {
//Your request was not successful
/*
You can check the body of the response here anyways. Maybe your api does return a json error?
*/
}
}).catch(error => {
//error handling for fetch errors
}))
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 😃