Reputation: 1672
On trying to return some data from a GET
request via AJAX
, I'm continuously greeted with this nasty error message ...Unexpected token { in JSON...
and I can clearly see where it's coming from. Note that this only happens if I have more than one(1) item being returned from the database. If I only have one(1) item I am able to access it data.id
, data.user_name
, so on and so forth.
{
"id":"39",
"user_id":"19",
"user_name":"Brandon",
"content":"Second Post",
"date_created":"2018-01-24 21:41:15"
}/* NEEDS TO BE A ',' RIGHT HERE */ {
"id":"37",
"user_id":"19",
"user_name":"Brandon",
"content":"First",
"date_created":"2018-01-24 15:19:28"
}
But I can't figure out how to fix it. Working with data, arrays, and objects is an artform I have yet to master.
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost/mouthblog/test.php');
xhr.onload = () => {
if (xhr.status == 200) {
const data = xhr.responseText;
const jsonPrs = JSON.parse(data);
console.log(jsonPrs);
} else {
console.log('ERROR');
}
};
xhr.send();
<?php
class BlogRoll extends Connection {
public function __construct() {
$this->connect();
$sql = "SELECT `id`, `user_id`, `user_name`, `content`, `date_created`
FROM `posts`
ORDER BY `date_created` DESC";
$query = $this->connect()->prepare($sql);
$result = $query->execute();
if ($result) {
while ($row = $query->fetch(PDO::FETCH_OBJ)) {
header('Content-Type: application/json;charset=UTF-8');
echo json_encode($row);
}
} else {
echo 'NO POSTS TO DISPLAY';
}
}
}
I've been at this for a couple of hours now, everything similar to my problem on SO seems to be something different and I can't really find a decent plain JavaScript tutorial on returning real data. Everyone wants to use jQuery.
Upvotes: 1
Views: 127
Reputation:
You must print only once, e.g. a data "package" from which you will reference the items on the client-side correspondingly. But in your code you're actually printing for each row a data "package".
The solution is to create an array and save the whole fetched data into it. After that the array should be json-encoded and printed.
if ($result) {
// Save the fetched data into an array (all at once).
$fetchedData = $query->fetchAll(PDO::FETCH_ASSOC);
// Json-encode the whole array - once.
// header('Content-Type: application/json;charset=UTF-8');
echo json_encode($fetchedData);
} else {
echo 'NO POSTS TO DISPLAY';
}
Upvotes: 1
Reputation: 41
The reason why your code is failing is because you are using
echo json_encode($row);
This will echo an array for every row, but it is not valid JSON. I have corrected your PHP code (note: it has not been tested)
<?php
class BlogRoll extends Connection {
public function __construct() {
$this->connect();
$sql = "SELECT `id`, `user_id`, `user_name`, `content`, `date_created`
FROM `posts`
ORDER BY `date_created` DESC";
$query = $this->connect()->prepare($sql);
$result = $query->execute();
$returnArray = array(); // Create a blank array to put our rows into
if ($result) {
while ($row = $query->fetch(PDO::FETCH_OBJ)) {
array_push($returnArray, $row); // For every row, put that into our array
}
} else {
// Send the JSON back that we didn't find any data using 'message'
$returnArray = array(
"message" => "No data was found"
);
}
header('Content-Type: application/json;charset=UTF-8'); // Setting headers is good :)
exit(json_encode($returnArray)); // Exit with our JSON. This makes sure nothing else is sent and messes up our response.
}
}
Also, you stated this:
If I only have one(1) item I am able to access it data.id, data.user_name, so on and so forth.
That is correct because the array only contains that one item. The example you would access it via data.0.id, data.1.id, data.2.id, etc as each row is in its own array.
Upvotes: 1