Jump to content

Unexpected end of JSON input


wisconsinWildcat

Recommended Posts

Newbie here.

I have an ajax method in jquery calling a PHP class to search a database and return a single column in jSON, but I'm getting the "unexpected end" error message.

It doesn't have to be jSON if there's an easier or more sure way.

This is the meat of the jSON call. It was used for a ColdFusion component and was modified for PHP, so it's possible I left some chaff behind and don't recognize it.

    $.ajax({
        url: '../../../components/jobsDatabase.php',
        method: 'POST',
        dataType: 'json',
        data: {
            method: 'getAllRoles',
            returnFormat: 'json'
        },
        success: function(data) {
            var $optList = $('#rolesTitle');
            console.log('Success retrieving data.',data);
            $optList.empty();
            $optList.append('<option selected="true" disabled>Choose Job</option>');
            $optList.prop('selectedIndex',0);
            $.each(data, function(i,val){ 
                $optList.append('<option value="'+data[i]['role']+'">'+data[i]['role']+'</option>');
            });
            console.log('Done loading options.');
        },
        error: function(xhr, textStatus,errorThrown){
            console.log(xhr);
            alert(errorThrown);
        }
    });

Here's the class:

<?php
    class jobsDatabase {
        public $role;
        public $tag;
        public $location;
        public $job_id;
        
        function __construct( $role, $tag, $location, $job_id ) {
            $this->role     = $role;
            $this->tag      = $tag;
            $this->location = $location;
            $this->job_id   = $job_id;
        }
        
        function getAllRoles() {
            include( "connect_database.php" );
            $sql = "SELECT role FROM thedatabasenamehere.uniqueroles ORDER BY role";
            $json = array();
            $result = mysqli_query( $dbhandle, $sql );
            mysqli_close($dbhandle);
            while($row = mysqli_fetch_assoc($result)) {
                $temp = array( 
                    'role' => $row["role"]
                );
                array_push( $json, $temp );
            }

            $jsonstring = json_encode($json, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_FORCE_OBJECT);
            echo $jsonstring;

            die();
        }
    } // End of the class jobsDatabase
?>

I've run the connect-to-database and SQL/select separately and they work fine.  I wish you could easily use console.log() in PHP, it would sure help with debugging!   Yes, I use a real database name for "thedatabasenamehere".  I started the encode with no options, been trying some things out of desperation.

Also, shouldn't it "return $jsonstring" instead of echo it?  All the online references I found used echo so I'm confused.

Any help greatly appreciated.

Thank you!

WW

Link to comment
Share on other sites

Couple questions here, but the big one is this: you are calling the jobsDatabase::getAllRoles() method, right?

In your ajax target script (../../../components/jobsDatabase.php) you instantiate a jobsDatabase object, then call getAllRoles() on that object, right? If so, then yes, it might make more sense to return from the method instead of directly outputting (you'd have to dump the returned value from the instantiated object). At this point var_dump() $json after your while loop and check the network tab of your browser's developer's tools to see what the output is.

If you're not doing that, then that would be the problem - you're never going to get data from a method you don't call inside and object you don't instantiate.

Link to comment
Share on other sites

"you are calling the jobsDatabase::getAllRoles() method, right?"

Um...I definitely think so? ?

I thought the jQuery ajax code did that.  I also include it.  I posted everything pertinent. By virtue of you asking that question,  though,  you make me doubt that. 

How should I be making this event driven call?

Link to comment
Share on other sites

What taquitosensei just posted is what I was talking about. Ajax is connecting to the file jobsDatabase.php and will parse that file. But if there's no action in the script (like instantiating the object and calling the getallRoles() method), nothing will happen.

Link to comment
Share on other sites

From the jQuery documentation:

Quote
  • method (default: 'GET')
    Type: String
    The HTTP method to use for the request (e.g. "POST", "GET", "PUT"). (version added: 1.9.0)

The AJAX call will connect with the script assigned to the url parameter of settings object. In that script is where some action has to take place. For instance, in WordPress you pass a field named 'action' in your dataset to admin-ajax.php. admin-ajax.php then uses the value of that field to know what PHP functions to call in order to get you the data you need. What taquitosensei and I are suggesting is that you add the following to the end of he script - after the closing bracket of your class definition:

$job_data = new jobsDatabasee();
$data = $job_data->getAllRoles();
die($data);

and change `echo $json` to `return $json` inside the getAllRoles() method.

Before you do that however, what does the response header show in your devtool's network tab after the AJAX call has been made?

Link to comment
Share on other sites

I just took a look at the code again. I missed the 'method' in your data set - so, yes it's possible that is all being handled behind the scenes and not something you need to worry about. (Sorry - it's Monday in a big way here...)

So that begs the question, what does the response show in your browser's devtool's network tab?

Edited by maxxd
Link to comment
Share on other sites

15 minutes ago, wisconsinWildcat said:

I do get the error "SyntaxError: Unexpected end of JSON input" popping up from the ajax error output though.

Right, and we need to see what the actual JSON string is. If you're using Chrome, select 'More Tools > Developer Tools' from the menu (option - command - uppercase 'i' on a mac, Ctrl + Shift + uppercase 'i' on Windows). You'll see the 'Network' tab along the top - select that, then trigger your ajax call. You'll see 'jobsDatabase.php' under the 'Name' column. Click it, then select the 'Response' tab from the details screen that appears. This will show you the raw JSON output, which may have a slightly more helpful error message.

Link to comment
Share on other sites

You should be able to browse to jobsDatabase.php?method=getAllRoles and see your json. If you don't then the php to echo the json isn't being called. You do need to echo the $data. Just doing die($data); will end the script without sending the json data.   The ajax call is on the client side and it posts to the php page which then runs  and outputs the json data which the ajax call receives in the success and processes. 

Link to comment
Share on other sites

Sadly, "/jobsDatabase.php?method=getAllRoles" shows nothing. I changed it to "echo $jsonstring;" and still nothing.

 

Here's what Headers show when I call it with url/script?method  (I think I changed just enough to protect my client and my workstation) which makes it look like I'm making the trip there successfully, but it results in no data output:

    1.  
      Request URL:
      http://domain-name-here/components/jobsDatabase.php?method=getAllRoles
      Request Method:
      GET
      Status Code:
      200 OK
      Remote Address:
      xxx.xxx.200.71:80
      Referrer Policy:
      no-referrer-when-downgrade
      Response Headersview source
      Content-Length:
      0
      Content-Type:
      text/html
      Date:
      Mon, 18 Mar 2019 19:27:19 GMT
      Server:
      Microsoft-IIS/7.5
      X-Powered-By:
      ASP.NET
      X-Powered-By-Plesk:
      PleskWin
      Request Headersview source
      Accept:
      text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
      Accept-Encoding:
      gzip, deflate
      Accept-Language:
      en-US,en;q=0.9
      Cache-Control:
      max-age=0
      Connection:
      keep-alive
      Cookie:
      PHPSESSID=7hg9abcdefg8ii5rjtne1chph3g1
      Host:
      domain-name-here
      Upgrade-Insecure-Requests:
      1
      User-Agent:
      Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
      Query String Parametersview sourceview URL encoded
      method:
      getAllRoles

       

    1.  
Link to comment
Share on other sites

If that's all the code there is and you're not using a framework, then yes, you need to call the method on the object.

Add this to the bottom of your file:

$job_data = new jobsDatabase(0,0,0,0);
$data = $job_data->getAllRoles();
die($data);

Note that anything happening here is dependent on the contents of connect_database.php.

While you're learning it may be a little easier to create a static array inside getAllRoles() and output that. That way you know everything is self-contained and you know what you're expecting. This should make it easier to track down any issues and errors in the process.

Link to comment
Share on other sites

I followed answer 2 on https://stackoverflow.com/questions/17356469/how-to-call-a-class-function-from-jquery-php and now do not get any errors, but it doesn't stuff the result back to the form. 

That's a different problem. I'll keep grinding.

Thanks for the help!

P.S. What I don't understand in that method is why I can't have it all in one file. My main page calls a js file that calls a single-use php file that instantiates an object from yet another file.  Seems like over-complication.

Edited by wisconsinWildcat
Link to comment
Share on other sites

Yeah, Jason Larke's answer is pretty much exactly what taquitosensei and I have been saying.

1 hour ago, wisconsinWildcat said:

...and are you recommending


jobsDatabase(0,0,0,0);

because there are four PUBLIC statements at the beginning, and this provides placeholders for them?

No. The 'public statements' before the __construct() method are called object properties or object variables. The reason I'm passing in 4 random values is because the constructor signature calls for 4 parameters to be passed in; you've got

22 hours ago, wisconsinWildcat said:

__construct( $role, $tag, $location, $job_id )

The first 0 is now assigned to $role, the second is $tag, third is $location, and fourth is $job_id. They're not used in the class you've written, so I passed in nonsense values.

59 minutes ago, wisconsinWildcat said:

What I don't understand in that method is why I can't have it all in one file. My main page calls a js file that calls a single-use php file that instantiates an object from yet another file.  Seems like over-complication.

There's a bunch of different reasons for having multiple files. The biggest is that AJAX is a client-side technology, but database interaction is a server-side technology. So you need to have the JavaScript file and a PHP file. The JavaScript is separate from the HTML file because if it was all in the same file you'd run a decent chance of breaking the functionality every time you change a DOM element.

The PHP is the server-side file that actually gathers the data and prints it back to the AJAX call. Adding the lines above to the jobsDatabase.php file will automatically create an instance of the jobsDatabase class and run the getAllRoles() method of that object, which in turn prints the gathered data.

Basically, you're dealing with a whole lot of moving parts with what you're trying to do. Given what we've talked about, I'll recommend again just stubbing in the data - instead of trying to use an additional PHP file to connect to the database and gather the actual data, just make up an array and print it to the AJAX call. In the AJAX success() callback, print that data to screen or console. Once you see the data you're expecting, move on to the next stage - in this case, populating the returned data in the form. From there, worry about actual database interaction.

Hopefully at least some of that makes sense - again, it's  been a bit of a Monday here.

Link to comment
Share on other sites

12 hours ago, wisconsinWildcat said:

I followed answer 2 on https://stackoverflow.com/questions/17356469/how-to-call-a-class-function-from-jquery-php and now do not get any errors, but it doesn't stuff the result back to the form. 

That's a different problem. I'll keep grinding.

Thanks for the help!

P.S. What I don't understand in that method is why I can't have it all in one file. My main page calls a js file that calls a single-use php file that instantiates an object from yet another file.  Seems like over-complication.

Because it doesn't work that way. Ajax is client side javascript that runs in the browser. It is not aware of the php page at all until you say,  send this data to jobsDatabase.php on the server and get me the results.

Link to comment
Share on other sites

I apologize for the delay in responding. Life threw me a couple curveballs I had to contend with.

Maxxd, I appreciate your explanation more than you know. I've been in the computer field and programming since 1978 and I've forgotten more languages (most self-taught, many in the mainframe realm, then PC's when they came out: MAPPER, SSG, Basic, Pascal, Fortran, COBOL, Assembler, PowerBuilder, dBASE, Foxpro, and on and on) than most programmers ever learn, but I never did quite get the ajax stuff, and I'm brand new to PHP.  Your explanation helps me a great deal, and I feel it's going to help more folks who stumble upon this thread.

Barand, I have an include file for my connection, and I include that file before every database action.  Perhaps it's not correct for PHP, but in past programs I've learned to re-use programs and minimize the amount of code I ever have to re-write for new systems. I'd bet you do as well.  I'm sorry I didn't include the entire file, but I am trying to protect my client.

taquitosensei, Thanks for chiming in.  One day, this will all click, like it's done for so many programs before, and I'll be off and running.

I certainly appreciate all the help from all of you! Thank you!   I'm not "there" yet, but I hope to be soon.

May you all enjoy 41+ years of programming!  And I'm nowhere near done yet.  PHP / Ajax / MySQL is just the next thing for me.

Edited by wisconsinWildcat
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.