I'm sending a JSON request (an applicative login
but the kind of request doesn't matter) to a server with the following function:
function login() {
var payload = {
"api_key" : "", "cmd" : "login",
"params" : {}
}
payload["params"]["username"] = document.getElementById("uname").value
payload["params"]["password"] = document.getElementById("passwd").value
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:4000/api", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
resp = JSON.parse(xhr.responseText);
console.log("resp.status=" + resp.status);
console.log("resp.[\"status\"]=" + resp["status"]);
}
}
xhr.send(JSON.stringify(payload));
}
I'm actually getting the correct reply in the responseText
field. For example, if the credentials are wrong, I get
{
"status": "ko",
"errors": [
{
"cmd": "login",
"long": "Login error : 'user-20' has no access to the system",
"short": "login_error"
}
]
}
If the credentials are OK I get
{
"status": "ok",
... some additional data
}
Yet, I can't manage to get the status
field : resp.status
or resp["status"]
are always undefined
. Same if the call is done in asynchroneous mode (xhr.open("POST", "http://localhost:4000/api", false);
) or if I don't JSON.parse()
the reply, ie: resp = xhr.responseText;
.
Update - 2017.09.06
I finally found a way to get it working, but I don't quite understand why it is so. I actually changed
resp = JSON.parse(xhr.responseText);
into
resp = JSON.parse(JSON.parse(xhr.responseText));
To figure this out, I printed typeof(xhr.responseText)
which is a sting
. Actually typeof(JSON.parse(xhr.responseText))
is also a string
and this is why it has no fields like status
. Eventually, parsing xhr.responseText
twice gives an object
from which I actually can retrieve my data.
If somebody has a clue about what is happening, I would be interested... I don't know if this is related, but the app server that is sending the JSON is the latest version of Elixir/Phoenix, ie, 1.5/1.3 and JSON encoding/decoding is done with poison.
This is because you have assigned the resp variable to responseText
resp = JSON.parse(xhr.responseText);
To get the response code
respCode = xhr.status
Or if you want both in the same resp
variable you could do
resp = {
responseText: xhr.responseText,
status: xhr.status
}
Then you can access them as resp.responseText
and resp.status