1

I've been having an issue with AJAX parsing a JSON Array from a webservice I'm creating. My front end is a simple ajax & jquery combo to display results returned from the webservice I'm creating.

I'm getting an error within Chrome's console stating "cannot read the length property of undefined" despite knowing that there are results from my database query.

After looking for an answer for days I still cannot figure out why I get the console error.

Thank you for any help! :)

function ajaxrequest(e)
{	
	var r = $('#region').val();
	var t = $('#type').val();
	console.log(r,t);
	$.ajax('https://URL...../.../POI/POI_LOOKUP.php',
	{ type: 'GET',
				data: 'type='+t+'&region='+r+'&format=json',
				success: onSuccess }
	);
}

function onSuccess(data,status,xmlHTTP)
{
	var html = "<table><th>name</th><th>type</th><th>country</th><th>region</th>";
	for(var i=0; i<data.length; i++)
	{
	html = html + '<tr><td>' + data[i].name + '</td>' + '<td>' + data[i].type + '</td>' + '<td>' + data[i].country + '</td>' + '<td>' + data[i].region + '</td></tr>'; 	
	}
	html = html + '</table>';
	$('#results').html(html);
	console.log(data);
	console.log(status);
}

Here is my PHP to search and return all results:

IF ($type == "any" && !isset($region)) /* Search DB for all types of POI for all regions*/
    {
        $statement = $conn->prepare("SELECT * FROM pointsofinterest;");
        $statement->execute();
        $row = $statement->fetch();

        if ($row == false)
        {   
            header("HTTP/1.1 204 No Content");
        }
        else
        {
            $allResults = array();
            while($row != false) 
            {
                $allResults[] = $row;
                $row = $statement->fetch(PDO::FETCH_ASSOC);
            }
            echo json_encode($allResults);
        }
    }
10
  • What do you see if you console.log(data); at the start of onSuccess? Commented Dec 22, 2016 at 15:28
  • Uncaught TypeError: Cannot read property 'length' of undefined at Object.onSuccess [as success] (POI_HOME.html:35) at c (jquery.min.js:4) at Object.fireWith [as resolveWith] (jquery.min.js:4) at k (jquery.min.js:6) at XMLHttpRequest.r (jquery.min.js:6) onSuccess @ POI_HOME.html:35 c @ jquery.min.js:4 fireWith @ jquery.min.js:4 k @ jquery.min.js:6 r @ jquery.min.js:6 Commented Dec 22, 2016 at 15:35
  • Basically no data when I know the SQL query is working fine. Commented Dec 22, 2016 at 15:36
  • I can see that you haven't decoded the JSON coming back from the web service. Either you need to specify, dataType: "json", in your jQuery Ajax call. Or you need to perform something like var jsonData = JSON.parse(data) in the first line of you onSuccess function. Commented Dec 22, 2016 at 15:40
  • Other queries run depending on what the users enters on the front end, but this error will come up if there are no results returned too. So it works to an extent but for the first query (posted) and ones where no results are returned it seems my web service is encoding and empty JSON array? Commented Dec 22, 2016 at 15:43

1 Answer 1

0

Ideally you should pass back empty results, if there are no results, and let the Javascript decide what to do (display a nice friendly message to the user). I haven't tested this, it's just for guidance, be warned.

PHP

if ($type == "any" && !isset($region)) /* Search DB for all types of POI for all regions*/
{
        $statement = $conn->prepare("SELECT * FROM pointsofinterest;");
        $statement->execute();
        $results = $statement->fetchAll();
        if (count($results)!=0){
            echo json_encode($results);
        } else {
            header("HTTP/1.1 204 No Content");
        }
}

JAVASCRIPT

You may want to handle the 204 response separately: How to handle a 204 response in jquery ajax?. The code below assumes you may receive an empty JSON response.

function onSuccess(data,status,xmlHTTP)
{
    if (data.length==0) {
       alert("Friendly user message"); 
       return;
    }
    var html = "<table><th>name</th><th>type</th><th>country</th><th>region</th>";
    for(var i=0; i<data.length; i++)
    {
    html = html + '<tr><td>' + data[i].name + '</td>' + '<td>' + data[i].type + '</td>' + '<td>' + data[i].country + '</td>' + '<td>' + data[i].region + '</td></tr>';  
    }
    html = html + '</table>';
    $('#results').html(html);
    console.log(data);
    console.log(status);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your responses guys, it's appreciated. In order to display a message to the user I was going to use the header information Guillermo. As it's a webservice I'm creating clients will use the header info to display their own custom messages. I tried the code you posted with no luck, possibly due the lack of stating the array?
The idea is to always return valid JSON even if there are no results. fetchAll() should always return an array even if there are no rows: php.net/manual/en/pdostatement.fetchall.php. You can check the length first if you wish to send a 204 response. I'll modify my answer. You will of course, have to handle the 204 response in you Ajax call.
I understand that Guillermo. It seems that checking if the $region variable was not set resulted in no results, I edited it to just check if its blank ( $region =="") and I'm now getting results. I tried your suggestion (PHP) for my web service and all my results were coming back as undefined. I now face the challenge of sending a blank valid JSON response to stop the "Cannot read length" console error I get when no results are returned.
Thanks you everyone for taking time out to help me! Much appreciated!

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.