React, how to debug (axios) 404 error? - reactjs

Using React, I am trying to make a request using axios.
In the console it shows me that I get an 404 error, but I would like to know how and why this is happening. Can anybody advice me on where to begin looking to solve this problem?
One of my main questions is, where is the following url coming from?
GET http://127.0.0.1:3000/en/order/account/[object%20Object] 404 (Not Found)
It seems like a request is being made to the above url, while that is not the url that is supposed to be requested. The url that should be requested is printed out, to check if it is correct.
On the (Django) development server, running at :8000, I am checking if a request is coming in. There I can see that indeed no request is coming in, not at the intended url (the one being logged to the console).
I have taken a look at the lines in the files being pointed at by the error line on the console (createError.js:16, settle.js:18, xhr.js:77), but that doesn't make it much clearer what happened. I guess this is just saying that that is the error is formed with the code in 'createError.js'.
This is what I see in the Chrome console:
Here is the part of the code that performs the axios request:
handleSubmit(submittedValues) {
console.log("submit")
console.log(submittedValues)
// event.preventDefault();
this.register(submittedValues).then(
function (data) {
console.log(data)
}
)
console.log("this.props.match.params.locale: " + this.props.match.params.locale)
let url = 'http://127.0.0.1:8000/customer_portal/set_locale/' + this.props.match.params.locale
console.log("url: " + url)
return axios.get({
url: url,
method: 'get',
})
.then(function(response) {
console.log(response)
})
.catch(function(error) {
console.log("error", error)
})
}

Try
axios.get(url)
axios.get() takes a string as an argument, but you're giving it an object so it is inserting the default URL path automatically before inserting the object.

Related

Axios .get request weird behaviour

I have the following get request:
return axios
.get<ArticlesResponse>(SUGGESTED_ARTICLES, {
headers: {
'Content-Type': 'application/json',
},
})
.then(onRequestSuccess)
.catch(onRequestError);
It returns me an object with the data I need, however, the data field inside the object is a string instead of an actual object. Anyone has any ideea about why? I looked it up and saw that adding that header above will fix the issue but it doesn't. Thanks in advance!
My onRequestSucces is:
export function onRequestSuccess<T = any>(response: AxiosResponse<T>) {
console.log('Request Successful!', response);
return response.data;
}
JSON.Parse() also won't fix it.
The problem may be due to the API returning a response that contains invalid JSON data, now JSON.parse would throw an error, but Axios manages the exception by setting the invalid JSON as string in the data property. Try using the Fetch API.
Since you're using a GET request (doesn't have a body) the 'Content-Type' is not being useful. This header is used to tell the server which type of content you're sending, but you're sending none. You should use it only on POST/PUT requests.
See this question for more details on this.
In order for your request to be read as JSON you have to set the header in the server. This will tell the browser you're receiving a JSON, which will then be parsed automatically by axios.

JSON.stringify in response option of cy.route is not working

I'm currently writing tests on Cypress for an application writen in react and using redux and redux-saga. For one of my tests, I'm trying to stub a request and returning a response that the code is expecting to be an 'stringified' array by JSON so it can be parsed later.
I've tried to specify a response in the cy.route() command using JSON.stringify([desiredResponse]) but that is not working, response keeps being kind of parsed by Cypress or some other middleware before getting to the saga.
I've also tried to intercept the response in the onResponse option but seems to me like that's being executed once the response was delivered (not sure about this, made a couple of vague tests only)
// This is how my cy.route() config looks like
cy.route({
method: 'POST',
url: 'someUrl',
response: JSON.stringify([myResponse]),
});
And in my saga:
// I call the url via axios and immediately after I try to parse it
try {
const parsed = JSON.parse(response.data);
} catch (err) {
const parsed = [];
}
I would expect my response in the saga to be something like: "[myResponse]" but I got the raw array instead
Out of curiosity: have you tried avoiding to wrap [myResponse] into JSON.stringify()?
Something like
cy.route({
method: 'POST',
url: 'someUrl',
response: [myResponse],
});
Anyway: in my app, with your exact situation, my only difference with your code is that I leverage the Cypress fixtures .
Could you share a simple GitHub repo with your simplified code?

angularjs custom REST action and error handling

I'm having some trouble with error handling in a little angularjs application. I'm interacting with a Flask backend and a Postgres DB.
I have a factory service
appointServices.factory('Appointments', ['$resource', function($resource){
return $resource(someUrl, {}, {
query: { ... }
,
create: {
method: 'POST'
,url: 'http://somedomain:port/new/:name/:start/:end/:treatment'
,params: { start: '#start', end: '#end', name: '#name', treatment: '#treatment' }
,isArray:false
}
});
}
]);
Inside a controller I'm making the following call
Appointments.create($scope.appointment, function(value, responseHeaders) {
// success handler
console.debug('success: ', JSON.stringify(value));
}, function(httpResponse) {
// error handler
console.debug('error: ', JSON.stringify(httpResponse));
});
Here $scope.appointment contains the relevant parameters for the create action.
Now, in the backend I'm able to catch DB errors involving constraints and I'm trying to return an error code with a 'meaningful' message. So I have a python method
def create(name, start, end, treatment):
try:
...
transaction_status = 'ok'
code = 200
except IntegrityError as e:
...
transaction_status = 'IntegrityError'
code = 500
finally:
...
return make_response(transaction_status, code)
Everything works fine, I'm able to talk to the backend, create new data and insert this in the DB. As I said, any violation of the constraints is detected and the backend responds
curl -X POST "http://somedomain:port/new/foo/bar/baz/qux" -v
...
< HTTP/1.0 500 INTERNAL SERVER ERROR
...
IntegrityError
So, the problem is, no matter whether the action create was successful or not, the intended error handler specified inside the controller is always fired. Moreover, I always end up with a status code 404 in the httpResponse. Firebug shows correctly the code 500 as above, though.
Anybody has any idea of why I'm getting this behavior?
Any suggestions on how to improve the error handling mechanism are also welcome.
Thx in advance.
P.S. Following the documentation on $resource I have also tried variations on the factory service call, e.g.
Appointments.create({}, $scope.appointment, successCallback, errorCallback);
Appointments.create($scope.appointment, {}, successCallback, errorCallback);
with the same results.
Update:
Forgot to mention the important fact that I'm interacting with the backend via CORS requests. The POST request in create above is having place with the OPTIONS method instead. As I mentioned everything is working correctly except for the error response.
Under further investigation, I tried to isolate the factory service, in case I did something wrong, and I also tried the approach shown in the credit card example ($resource docs), but with no positive result.
However, I came up with two workarounds. Firstly, I was able to create a plain JQuery POST request, as in the example shown in the docs. This time, the request is not replaced by OPTIONS and I got the error code correctly.
I also managed to connect to the backend with the low-level $http service as follows:
var urlBase = 'http://somedomain:port/new/:name/:start/:end/:treatment';
var url = urlBase.replace(/:name/g, $scope.appointment.name);
url = url.replace(/:start/g, $scope.appointment.start);
url = url.replace(/:end/g, $scope.appointment.end);
url = url.replace(/:treatment/g, $scope.appointment.treatment);
// force method to be POST
var futureResponse = $http({ method: 'POST', url: url });
futureResponse.success(function (data, status, headers, config) {
console.debug('success: ', JSON.stringify(data));
});
futureResponse.error(function (data, status, headers, config) {
console.group('Error');
console.debug(JSON.stringify(status));
console.debug(JSON.stringify(data));
console.groupEnd();
});
This time, as in the case of JQuery, the request is done effectively with POST and error codes are correctly received.
Notice also that I'm not calling $http.post but I set the method to POST as part of the object parameter to $http, otherwise the connection takes places with OPTIONS as before.
Still trying to figure out what is happening with $resource.

303 redirection not working with Angular HTTP POST

I am calling an authentication service where I do a $http.post which returns a 303 resonse, redirecting to a get call returning the response.
When I make the post call using Postman, I get the desired response but when I do an angular $http.post call, it returns me a 401 error (which is user not authorized)
Am I missing something while making the angular call? The backend service seems to work fine as it works fine on Postman.
This is how the $http call looks:
$http.post(url, userData).success(function(data, status) {
//handle success
}.error(function(data, status) {
//handle error
});
The url and the user data is constructed absolutely fine in this case.
The reason that you get a GET call is that the browser handle the 303 response before the angular can reach that. And the handling sequence is first go to the browser and then go to the angular framework.
So briefly what happens is : you make call to the server --> the server return the 303 response -> your browser handle the 303 and make a request to some url (should be 'location' in the response header) --> the server receive the request and return the 401 authorized response --> again the browser receive the 401 response first but this time the browser redirect the response to the angular --> at last you can receive the data and status inside the error().
The solution for this could be switching to other response status code like 2xx, and you can get the location from the body. Then you can do the redirection manually. If you HAVE to use 303 or other 3xx as the response code I don't think there's any effective solution at this moment because you can't do much to the browser. As far as I know there might be a solution at browser level but don't know when that will happen.
Hope this can help anyone has the similar issue like this although it has been nearly one year since this issue raised.
Some other ref: https://groups.google.com/forum/#!topic/angular/GKkdipdMbdo
There's similar solution you can see from the link above.
I faced this issue and I found a redirect url in error object after lots of hours struggle.
loginWithLinkedIn() {
let data = {
// some kind of information here
}
return this.http.get(`https://www.someurl.com/oauth/v2/authorization`).subscribe(res => {
console.log(res)
}, err => {
console.log(err.url) // here is the redirect url
window.location.href = err.url
})
}
Note: when you make a request and you get 303 response which is considered as error, that's why we think we are getting error but error contains useful info.

destroy always returns with the error callback (although everything seems to be ok)

I'm trying to delete a model on my backend and what I do is this (the code is adapted just to show you the issue, some parts could be missing):
attending= new Backbone.Model();
attending.url= this.url() + "/reject";
attending.set({
id: this.id
})
attending.destroy({
success: function(){
alert("yes");
},
error: function(){
alert("no");
}
});
but what I always obtain is a "no" alert. The fact is the backend seems to be updated correctly and what I obtain as a response too. Here it is:
so... what's wrong with the response I get? Why doesn't backbone recognizes it as a successful response? I get 200/OK and a "application/json" format as well!
Your backend should return something with 200
jQuery expect 200 with application/json to have some content
Have a look here: https://github.com/jashkenas/backbone/issues/2218#issuecomment-20991938
You might want to place a "debugger;" in the error callback and trace exactly why its coming that route vs the success route. That should atleast get your started on the right path...

Resources