0

I'm trying to return a query made in a controller to the view file so I can use that data in my form. But I am unable to successfully return the data without errors. I know the function is working because it returns the right data but has an error.

Here is my CustomersController fill function which is running the sql query.

public function fill(){
        $layout = 'ajax';
        $this->autoRender = false;
        if ($this->request->is('post')) {
            $id = $this->request->data['id'];
            $query = $this->Customers->find()
            ->where([
               'id' => $id
            ])->first();
            echo json_encode($query);  
       }  
}

and here is my blah.ctp which is the view file.

<?php use Cake\Routing\Router; ?>
<?= $this->Form->create(Null, ['type' => 'POST']) ?>
<?php
    echo $this->Form->input('customer_id', ['options' => $customers, 'empty' => true,'id'=>'customers']);
?>
<?= $this->Form->end() ?>

<script>
document.getElementById('customers').addEventListener('change',function(){
   var id = this.value;
    var csrfToken = $('[name=_csrfToken]').val();
    $.ajax({
        type: "POST",
        url: '<?php echo Router::url(array("controller" => "Customers", "action" => "fill")); ?>',
        data: {'id' : id},
        beforeSend: function(xhr){
           xhr.setRequestHeader('X-CSRF-Token', csrfToken);
        },
        success: function(data){
            alert(data);
        }
    });
});
</script>

Currently this is what happens when I select a customer in my drop down box which triggers the script in the view. enter image description here As you can see it returns the array of data I need but also has the error cannot emit headers. I have tried solving this error following other questions on stack overflow but can't solve it. I've tried using $this->set instead of echo json_encode but it always returns nothing. I'm not sure what other way to do this.

1

1 Answer 1

1

First of all, If you're selecting a single record by a unique ID, you can call ->get($id) on the table object directly, instead of building a query chain with ->find().

CakePHP 3.x should automatically handle converting your view to JSON by using the RequestHandlerComponent. Typically, you must enable it if your scaffolding or installation didn't.

1) Enable request handler component. (If not already enabled) https://book.cakephp.org/3.0/en/controllers/components/request-handling.html

2) Remove the echo json_encode($query) line; you should not echo anything as this will break the request/response cycle. This is the cause of your error. Instead, you should serialize your data to the view. Assuming you have the fetched data in $data: $this->set(compact('data')). Then, make sure you add $this->set('_serialize', ['data']) (again, assuming the data is stored in variable name 'data').

3) Reference this doc for information on how you can request the json. You can use a file extension (.json, .xml). Also, make sure you add the 'Accept: application/json' header to your request.(https://book.cakephp.org/3.0/en/development/routing.html#Cake\Routing\Router::extensions).

I apologize for the fuzzy response. There are many ways to achieve this with CakePHP3. Please see this doc page for more information: https://book.cakephp.org/3.0/en/views/json-and-xml-views.html

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

5 Comments

Oh I forgot the request handler but sadly it didn't make a difference to when I tried $this->set before and it still returns nothing to the view and says no response available. Also thanks for the first tip too.
Np. I forgot to mention to check your request headers. Make sure you have 'Accept: application/json' in your request.
request headers currently just says "Accept: /" do I need to modify the controller?
The Controller should be ok as long as you've changed it to use $this->set() and serialize. Just add the Accept: application/json header to your javascript.
hmm I added headers: { Accept: "application/json" }, to my script and it fixed he request headers but i still get blank data.

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.