2

I am trying to parse a JSON object received from my server. This is my server's response:

[
  {
    "idPais": "1",
    "nombre": "España"
  },
  {
    "idPais": "2",
    "nombre": "Grecia"
  },
  {
    "idPais": "3",
    "nombre": "Holanda"
  },
  {
    "idPais": "4",
    "nombre": "Finlandia"
  },
  {
    "idPais": "5",
    "nombre": "Suiza"
  }
]

In my script, I tried to get the objects with one array, but resp is always undefined.

function loadCountries(cont) { // Listado de paises con contenidos
  var i = 0;
  var method = 'GET';
  var path = appConstants.requestCountriesURL(cont);
  console.log(path);
  var xhr = new XMLHttpRequest();   
  xhr.onreadystatechange = function() {
    alert('Status es: ' + xhr.status + 'State es: ' + xhr.readyState);
    if(xhr.readyState == 4 && xhr.status == 200) {
      alert('Recogiendo respuesta...');
      resp = xhr.responseText;
    }
  }
  xhr.open(method, path, false); // Creamos la peticion
  resp = xhr.send(); // Guardamos la respuesta
  if(resp == false || resp == undefined) {
    alert('La lista de paises no se pudo obtener');
    return resp;
  } else {
    alert('La lista de paises se obtuvo correctamente');
    console.log(resp);
    var listaPaises = JSON.parse(resp);
    return listaPaises;
  }
}

The error shown is the following:

Uncaught SyntaxError: Unexpected token u in JSON at position 0

Edit with solution 1:

function checkCountries(i){
    alert('oncheckCountries');
    var answer=$('input[name^="radio-choice"]:checked').val();
    alert('val es: '+ answer);
    $('#divPaises').css('display','block');
    getCountries(answer);

}
function getCountries(continente){
    alert('on getCountries');
    loadCountries(continente);
}
function loadCountries(cont){ //Listado de paises con contenidos
    var i = 0;
    var method = 'GET';
    var path = appConstants.requestCountriesURL(cont);
    console.log (path);
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function(){
        alert('Status es: '+xhr.status+'State es: '+xhr.readyState);
        if(xhr.readyState == 4 && xhr.status == 200){
            alert('Recogiendo respuesta...');
            resp = xhr.responseText;
            if(resp == false || resp == undefined){
                alert('La lista de paises no se pudo obtener');
                return resp;
            }
            else{
                    alert('La lista de paises se obtuvo correctamente');
                    console.log(resp);
                    var listaPaises = JSON.parse(resp);
                    console.log(listaPaises[0]);
                    var size = Object.keys(listaPaises).length;
                    var select = document.createElement('select');
                    alert('Select creado');
                    select.name = 'selectPais';
                    select.id = 'selectPais';
                    for(i=0;i<size ;i++){
                            var option = document.createElement('option');
                            option.id = listaPaises[i].idPais;
                            option.value = listaPaises[i].nombre;
                            option.appendChild(document.createTextNode(listaPaises[i].nombre));
                            alert(option.getAttribute('value'));
                            select.appendChild(option);
                            }
                    document.getElementById('divPaises').appendChild(select);
                }
        }
    }
    xhr.open(method, path, true); //Creamos la peticion
    resp = xhr.send(); // Guardamos la respuesta    
}
5
  • Possible duplicate of How do I return the response from an asynchronous call? Commented Nov 24, 2016 at 18:46
  • 1
    Shouldn't you check the resp after you get the response back? Right now you are checking its even before the server has sent you response back .. Commented Nov 24, 2016 at 18:51
  • totally not duplicated of that post. Commented Nov 24, 2016 at 18:51
  • You are assign in the wrong place a value to resp. I think that you don't need this line resp = xhr.send(); , you are getting the answer here resp = xhr.responseText; Commented Nov 24, 2016 at 18:55
  • ^ Since you're making it synchronous you can resp = xhr.responseText; right after xhr.send(); as Rafael suggested. But I'd highly recommend to make it async to avoid blocking the entire page while waiting Commented Nov 24, 2016 at 19:13

2 Answers 2

2

Your issue here is that you are using the result of xhr.send() as the response, when it's not. If you want to parse the response you have to do it in the onreadystatechange listener, using xhr.responseText, like this:

xhr.onreadystatechange = function(){
    alert('Status es: '+xhr.status+'State es: '+xhr.readyState);
    if(xhr.readyState == 4 && xhr.status == 200){
        alert('Recogiendo respuesta...');
        resp = xhr.responseText;

        if(resp == false || resp == undefined){
            alert('La lista de paises no se pudo obtener');
        } else {
            alert('La lista de paises se obtuvo correctamente');
            console.log(resp);
            var listaPaises = JSON.parse(resp);
        }
    }
}

Also, you cannot return the response since that the request is asynchronous, so you have to either do everything inside your function, or use a callback function, like this:

function loadCountries(cont, callback) { // use a callback
    var i = 0;
    var method = 'GET';
    var path = appConstants.requestCountriesURL(cont);
    console.log (path);
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function(){
        alert('Status es: '+xhr.status+'State es: '+xhr.readyState);
        if(xhr.readyState == 4 && xhr.status == 200){
            alert('Recogiendo respuesta...');
            resp = xhr.responseText;

            if(resp == false || resp == undefined){
                alert('La lista de paises no se pudo obtener');
                callback(resp);
            } else {
                alert('La lista de paises se obtuvo correctamente');
                console.log(resp);
                var listaPaises = JSON.parse(resp);
                callback(listaPaises);
            }
        }
    }

    xhr.open(method, path, false);
    xhr.send();
}


// Create a callback
function myCallback(data) {
    // Do what you want with the data...
}

// Call the function like this...
function loadCountries(myCont, myCallback);
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer. In this case my request is syncronous, why can not i "return" values?
@Asier No, your request is asyncronous! You are using false on the last parameter of xhr.open(), so it's asynchronous.
I think no, true is async, false is sync. developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…
@Asier ok you're right, so you should put true in your request, which is better.
I solved it. I will post the answer. I do all without callback function at the moment but i will put the code on it. I already tried it but when i try to get listaPaises array on another array in the callback function, it fails and destiny array stay "undefined".
|
1

It is an asynchronous call and you are trying to handle it as a synchronous one.

  xhr.onreadystatechange = function() {
    alert('Status es: ' + xhr.status + 'State es: ' + xhr.readyState);
    if(xhr.readyState == 4 && xhr.status == 200) {
      alert('Recogiendo respuesta...');
      resp = xhr.responseText;
      //Do your stuff with resp here
    }
  }
  xhr.open(method, path, false); // Creamos la peticion
  xhr.send(); //Send will not return anything 

Check here if you want more examples: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

1 Comment

Thanks for the answer. Its correct but i read first another. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.