1

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.

JAVASCRIPT (AJAX)

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 (this is where the data is coming from)

<?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.

3
  • Your problem has nothing to do with jQuery. Your problem is that your JSON is not valid. JSON must be a single object. You need an array. Commented Jan 25, 2018 at 3:38
  • Right, I wasn't saying that about jQuery, just clarifying I want a plain JavaScript solution/explanation. Do I need to push that from my PHP side or from the JS side? I've tried using array_push($array, $row), where $array is an empty array and $row is what is being returned from the database in the while loop and I just get another syntax error unexpected < in JSON Commented Jan 25, 2018 at 3:41
  • Figure out why there is a < and get rid of it. Commented Jan 25, 2018 at 3:44

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

13 Comments

Thank you for this, very solid solution.
Interesting thing that exit(json_encode(...)). I didn't knew this trick ;-)
@aendeerei It terminates the current script, so basically like a giant return, but globally. You can alos give it an integer or string to print right before exiting.
I'd like to throw in that it seems you can't actually return it. Uncaught SyntaxError: Unexpected end of JSON input which might be obvious to some, but echo json_encode($returnArray); works just fine. Although I will use the exit() function from now on.
@CodyRobinson Thanks for the explanation. Indeed, like Brandon, I, too, plan to test and use it in the future.
|
1

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';
}

Comments

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.