Accepted answer by Rohan Kumar:
Changed $.post() into
$.post("monitor/loadEVents", function(data){
if(data && data.response){ // (didn't even have to change this for it to work, but I like this condition more than my own one)
console.log('Wow, it works.');
} else {
console.log(data);
}
},'json'); // put the third parameter as json
Original question below:
I'm trying jQuery AJAX for the first time in Zend Framework 2 (I've never worked with AJAX before at all). That being said, I don't have very extensive experience in working with JSON yet either, so please forgive me for rookie mistakes ;)
In my js file I'm calling a function in my controller to return a JSON object. My problem is that when I log 'data' to the console, it logs the structure of it just fine, but when I try to do something with the keys of 'data', their values come back as undefined.
This is where I call the function:
$('#loadmore').on('click', function(event){
$.post("monitor/loadEVents", function(data){
if(data.response == true){
console.log('Wow, it works.'); // Want this condition met, but it never is.
} else {
console.log(data); // so it logs data
}
})
});
Here's the function inside my controller:
public function loadEventsAction(){
$request = $this->getRequest();
$response = $this->getResponse();
if($request->isPost()){
$events = array('a bunch' => 'of stuff');
$response->setContent(\Zend\Json\Json::encode(array('response' => true, 'events' => $events)));
}
return $response;
}
This is how it logs data:
{"response":true,"events":{"a bunch":"of stuff"}}
What do I do so I can get to the response and events keys in 'data' properly?
Try this,
$.post("monitor/loadEVents", function(data){
if(data && data.response){
console.log('Wow, it works.'); // Want this condition met, but it never is.
} else {
console.log(data); // so it logs data
}
},'json');// put the third parameter as json
Read post()
Related
I have a datatables with some inputs in certain columns that are editable. I want to save the edited values in db.
This is my datatables:
The serialized datatables from values looks like this (if you print_r($_POST) for debugging):
javascript - I post the datatables form via ajax request to my laravel api controller method like this:
// Serialize the datatable table into post string
var poDetailUpdates = create_po_details_table.$('input').serialize();
// Call po api to save changes
$.ajax({
type: "POST",
data: poDetailUpdates,
url: '/api/po/update-create-lines/',
complete: function(response) {
if (response.status === 200) {
alert(response.responseText); // success
} else {
alert(response.responseText); // error
}
}
});
php - this is how I handle my form post in laravel:
public function postUpdateCreateLines() {
DB::beginTransaction();
try {
foreach ($_POST as $column_name => $values) {
foreach ($values as $line_id => $new_value) {
DB::table('purchase_order_details')
->where('id', '=', $line_id)
->update(array($column_name => $new_value));
}
}
DB::commit();
Response::make('Purchase order details updated', 200);
} catch (Exception $ex) {
DB::rollback();
Response::make('Purchase order details not updated - '. $ex->getMessage(), 500);
}
}
When the code runs, I get an empty alert() in javascript once the ajax request completes.
I thought the issue might be with the DB transaction related code, so I tried commenting out the following:
// DB::beginTransaction();
// DB::commit();
// DB::rollback();
But this also yields the same result (empty alert). Any idea what might be wrong? how to debug this? Something must be going wrong somewhere...
Your postUpdateCreateLines() method is not actually returning anything; you are making a response, but you need to return it:
return Response::make('Purchase order details updated', 200);
However, there are some other improvements you could make. It is best to return a JSON response to your $.ajax call, and then rely on jQuery's ajax .done and .fail handlers to deal with the response appropriately (rather than using complete):
return Response::json(
['status' => 'success',
'msg' => 'Purchase order details updated']
, 200)
...and add the response dataType to your ajax call:
dataType: "json"
I have an AJAX script that should insert data into a mysql database when users are logged in. However it is currently running the success function, even when 'success' => 'false' is returned in the console.
Her is my code
$(document).ready(function() {
$("#addfav").click(function() {
var form_data = {heading: $("#vidheading").text(), embed : $("#vidembed").text()};
jQuery.ajax({
type:"POST",
url:"http://localhost/stumble/Site/add_to_fav",
dataType: "json",
data: form_data,
success: function (data){
alert("This Video Has Been Added To Your Favourites");
console.log(data.status);
},
error: function (data){
if(data.success == false){
alert("You Must Be Logged In to Do That");
console.log(data.status);
};
}
});
})
})
here is the php, bear in mind my project is in codeigniter.
public function add_to_fav(){
header('Content-Type: application/json');
$this->load->model('model_users');
$this->model_users->add_favs();
}
and this is the actual model for adding data to db
public function add_favs(){
if($this->session->userdata('username')){
$data = array(
'username' => $this->session->userdata('username'),
'title' => $this->input->post('heading'),
'embed' => $this->input->post('embed')
);
$query = $this->db->insert('fav_videos',$data);
echo json_encode(array('success'=>'true'));
} else {
echo json_encode(array('success'=>'false'));
}
}
Thank you for any suggestions!
You aren't returning an error.
You are returning a 200 OK with the data {"success": "false"}.
You can either handle that in your jQuery success function or send a different status code (it looks like a 403 error would fit here).
You have to remember error that occurs for asynchronous requests and errors that occur for PHP backend are different. Your error occurs at PHP-level, and PHP returns valid HTML as far as the javascript frontend is concerned. You need to check if the "success" variable in the returned JSON is true.
I would like to ask you how could I send ajax request with serialized by jQuery form and recieve JSON response from controller? I have been trying many solutions but none of them worked for me. I have a little experience in that matter.
Can you provide any good example? Thank You!
Send post with serialized form (POST) by AJAX
Process action in controller function and obtain JSON response in ajax -> success
I'm using CakePHP 2.4.1
My ajax request
$.ajax({
type: "post",
url: location.pathname + "/edit",
data: data,
success: function(response) {
$("#content").html(response); // i would like to recieve JSON response
alert(response); // here ;C
},
error: function(){
alert("error");
}
});
Part of my function in controller
public function admin_edit(){
//................ some logic passed
if($this->request->is('ajax')){
$this->layout = 'ajax';
$this->autoRender = false;
$this->set(compact('user'));
$this->disableCache();
foreach($this->request->data['User'] as $key => $value){
if(empty($value)){
unset($this->request->data['User'][$key]);
}
}
$this->User->id = $this->request->data['User']['id'];
if($this->User->save($this->request->data)){
$this->Session->setFlash('Użytkownik został zmodyfikowany');
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash('Nie zmodyfikowano użytkownika');
}
}
What i would like to recieve is JSON response from the controller.
example
[{"id":"1", "username":"test", ... }]
Ok, I think what confuse you are little stuff, but mixed together can be a bit hard to debug for someone with little experience. I'll post a basic example of what should work for you, and you iterate over that. Tell us if there's another error (it's easier to check for specific errors rather than the view/controller possible error).
First, in the ajax call, change for console.log(response); to debug better
//alert(response);
console.log(response);
},
error: function(){
alert("error");
console.log(response);
}
});
And in the controller
public function admin_edit(){
//................ some logic passed
if($this->request->is('ajax')){
/* layout not necessary if you have autoRender = false */
//$this->layout = 'ajax';
/* actually, no need for this either with _serialize, but add it if you have unwanted html rendering problems */
//$this->autoRender = false;
$this->set(compact('user'));
/* other code that doesn't really matter for the example ... */
$this->User->id = $this->request->data['User']['id'];
if($this->User->save($this->request->data)){
/* NO!! */
//$this->Session->setFlash('Użytkownik został zmodyfikowany');
//return $this->redirect(array('action' => 'index'));
$status = 'OK';
$message = 'Użytkownik został zmodyfikowany';
$this->set(compact('message', 'status'));
}
/* NO EITHER!! */
//$this->Session->setFlash('Nie zmodyfikowano użytkownika');
$status = 'NOT-OK';
$message = 'Not sure what your flash says but let\'s assume it an error alert';
$this->set(compact('message', 'status'));
//serialize variables you have set for the "ghost" view
$this->set('_serialize', array('user', 'message', 'status'));
}
}
I think your major flaw here is to return a redirect. That's a no no for json. What you are doing with that is giving the ajax call the html for the index action. That makes no sense. If you want the action to return JSON, then all cases must return json, no html whatsoever. So, no setFlash, no redirect. What I normally do here is to return the JSON data with a status and a message (like in the code above). Then, in the ajax call, on success, you parse the JSON data, read the status, if ok you redirect (via js), and if not, show the error message you got.
Hope it clear things for you.
[tiny edit]: json_encode will also work, but when in CakePHP, do what CakePHP(ians?) do (serialize) (because you don't need to echo the variables).
There's an example at JQuery.com
Example: Post to the test.php page and get content which has been returned in json format
<?php echo json_encode(array("name"=>"John","time"=>"2pm")); ?>
.
$.post( location.pathname + "/edit", data, function( data ) {
console.log( data.name ); // John
console.log( data.time ); // 2pm
}, "json");
So plugging in your ajax call is something like:
$.post( "test.php", data, function(response) {
$("#content").html(response);
alert(response);
}, "json");
Edit: If you're not getting the correct response, please show the php code that echos or returns the json..it's not anywhere in that function you provided.
I need to pass json data to my Symfony Controller. My ajax function looks like this:
var data = '{"firstname":"John"}';
$.ajax({
type: "POST",
url: save_url, //path to controller action
data: {json:data},
success: function(response) {
// Do something
}
});
In my controller, I try to get my data through:
public function createAction(Request $request) {
$data = $this->getRequest()->get('firstname');
return $this->render('MyBundle:Counter:test.html.twig', array(
'data' => $data
));
Just to see if this works, I send $data to be echoed in a template. In Firebug I can see the data being sent and everything seems to work, but $data is empty and nothing is echoed. Where am I doing this wrong?
EDIT: When I check the response in Fireburg console, I see my data there, in place, but it never appears in the template. var_dump($data) tells that $data is null. So, it seems data is being sent but the controller ignores it.
As Marek noticed:
$this->getRequest()
already returns the request object, you're accessing the request property of the request, that doesn't add up. Either try:
$data = $this->request->get('json');
Or use:
$data = $this->getRequest()->get('json');
You can, of course assign the return value of $this->getRequest() to a variable, and call the get method on that var from there on end... anyway, here's my initial answer, it does contain some more tips, and considerations you may find useful:
You should be able to get the data this way, though AJAX requests + echoing in a template? That does sound a bit strange. I don't see you passing the $data variable to a $this->render call anywhere.
This is a copy-paste bit from a controller action in one of my projects. It works just fine there:
public function indexAction()
{
if (!$this->getRequest()->isXmlHttpRequest())
{//check if request is AJAX request, if not redirect
return $this->redirect(
$this->generateUrl('foo_bar_homepage')//changed this, of course
);
}
$id = $this->getRequest()->get('id',false);//works fine
However, I can't begin to grasp why you're doing this:
var data = '{"firstname":"John"}';
Why not simply go for:
$.ajax({
type: "POST",
url: url,//post how you get this URL please...
data: {firstname: 'John'},//jQ will sort this out for you
success: function(response)
{
console.log(response);
}
error: function()
{
console.log('an error occured');
console.log(arguments);//get debugging!
}
});
Then, in your controller you're able to:
$this->getRequest()->get('firstname');//it should be John
You could even pass {json:{firstname: 'john'}} as the data param to $.ajax, the only difference in your controller will be, that you have to do this:
$data = $this->getRequest()->get('json');
$firstName = $data['firstname'];
That should work just fine, unless there's somthing you're not telling us :)
RECAP:
This is what I'd write:
public function createAction()
{//no Request param in controller
if (!$this->getRequest()->isXmlHttpRequest())
{//no ajax request, no play...
$this->redirect(
$this->generateUrl('homepage_route')
);
}
$data = $this->getRequest()->get('firstname');
//return json response:
return new Response(json_encode(array('dataReceived' => $data));
//return rendered HTML page:
return $this->render('MyBundle:Counter:test.html.twig', array(
'data' => $data
));
}
Of course, then the JS code should read:
$.ajax({
type: "POST",
url: 'route/to/create'
data: {firstname:'John'},
success: function(response)
{
console.log(response);
}
});
I have tested this, and I see no reason why this shouldn't work. It works just fine for me...
Please note this was #EliasVanOotegem original example but there are some obvious steps missing
in the controller i'm reading a few replies as in "I cannot see how this works as i'm getting null" this is because your not correctly keying your object.
i.e.
var data = { name : 'john' };
$.ajax({
type: "POST",
url: url,//post how you get this URL please...
data: {json : data},//jQ will sort this out for you
success: function(response)
{
console.log(response);
}
error: function()
{
console.log('an error occured');
console.log(arguments);//get debugging!
}
});
as you can now see accessing the requerst object like
$request->get('json');
refers to the post key for the json data
Is the content what you're trying to retrieve, neither params nor headers.
Try:
$request->getContent();
In your case $request->request->get('json') should do.
I make an AJAX request like this
$.ajax({ type: "POST",url: "<?php echo site_url('home/view_most'); ?>",async: true,data: "view=most_booked", success: function(data)
{
if(data != 0)
{
$("#view_most").html(data);
}
else
alert("Error");
}
});
In controller i get through
public function view_most()
{
$view_most = $this->input->post("view");
}
The response that ajax request is what server echoes so you must echo some value to get the response and handle the response in your success function. In your case does not echo anything thats why you are not getting any response. For example:
public function view_most()
{
$view_most = $this->input->post("view");
echo '0';
}
Try this and you will get 0 as response.
not too familiar with the php codeigniter platform but I think you are not returning any data and that is why you dont see any data.. I am guessing you need to do something like the following at the end of your action code.
$this->load->view(viewName);
Thus your action code should be
public function view_most()
{
$view_most = $this->input->post("view");
$this->load->view($view_most);
}
Here is a quick introduction of AJAX on codeigniter: http://mrforbes.com/blog/2009/01/a-quick-code-igniter-and-jquery-ajax-tutorial/