Can't get data from controller with ajax request - php

Trying to get products from productController with category_id
As seen blow. Codes are basic ajax request codes, there is no complicated things. But my result is allways null.
ROUTE
Route::post('urun-listele', 'ProductController#listele');
CONTROLLER
public function listele(Request $request)
{
$category_id = $request['category_id'];
$urunler = Product::where('category_id', $category_id)->get();
#var_dump($urunler);
return json_encode([
'urunler' => $urunler
], JSON_UNESCAPED_UNICODE);
}
AJAX
function urunListele(kategori_id) {
var kapsayici = $('#product-info');
$.ajax({
url: 'urun-listele',
type: "POST",
data: {category_id: kategori_id},
dataType: 'json',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success: function (data) {
var urunler = data['urunler'];
for (var i = 0; i < urunler.length; i++) {
kapsayici.append('<div class="col-md-3 product-detail-item b-white br-10px"><p>' + urunler[i]['title'] + '</p></div>');
}
}
});
}
As i said, can't get any data.
var urunler = data['urunler'];
for (var i = 0; i < urunler.length; i++) {
kapsayici.append('<div class="col-md-3 product-detail-item b-white br-10px"><p>' + urunler[i]['title'] + '</p></div>');
}
console.log(urunler); allways return 0 object. Where is the problem? Thanks in advance.
EDIT:
i got Cannot read property 'length' of undefined when try return $urunler;
$category_id = $request['category_id']; can't get anything i think.
For example if i change $category_id = 5 it return [object Object],[object Object]
i have 2 object with $category_id = 5.
is problem here? $category_id = $request['category_id'];
EDIT2:
$category_id = $request->get('category_id');
$urunler = Product::whereCategoryId($category_id)->get();
return response()->json([
'urunler' => $urunler
]);
Controller changed like this and its working right now.

This could be due to a number of reasons first I am not sure if this is the correct syntax $request['category_id'];, but I may be wrong. I use most of the time `$request->category_id.
Second could you tell us wethere there is actual data here:
$category_id = $request['category_id'];
$urunler = Product::where('category_id', $category_id)->get();
Just dd($category_id) and dd($urunler) and tell us the results.
Furthermore you have a success method in your ajax request but not an error method could you add one and give us the results aswell?
Do something like this after your success function:
error: function(response) {
console.log(response) // this should hold a nice error message
}
Thus be sure that you actually post data in your ajax post, just console.log this kategori_id
At last laravel already returns a json by default so you do not actually need to do this, only if there is further reason for it.
You could replace this:
return json_encode([
'urunler' => $urunler
], JSON_UNESCAPED_UNICODE);
With this:
return $urunler;

Related

Dropdown Ajax Laravel ( Append, onChange, Method not Allowed )

i just learn about Ajax. I am so confused and getting error after following some tutorials. The plan is after we get the id_program, we can change or reload the page to show the data inside the dropdown menu after we clicks it. May someone help me please?
1.1 Database ( Program )
1.2 Inside Payment
1.3 Inside actor
DatabaseController.php
public function data($id)
{
$client = new Client();
$response = $client->request('GET', 'http://localhost:8585/api/v1/tables', [
'query' => [
'limit' => '100'
]
]);
$data = json_decode($response->getBody()->getContents(), true)['data'];
$pay = Payment::get()->all();
$pro = Program::select('nama')->where('name', $id)->get();
$coba = Program::get()->all();
foreach ($pro as $p) {
$name = $p->name;
}
return view('database.index', compact('nama','data','pay','coba','pro','id'));
}
Route
Route::get('program/database/{database}', [DatabaseController::class,'data'])->name('database.data');
database.index
<select id="id" class="form-control" filter>
<option>Pilih Layanan...</option>
#foreach ($coba as $id)
<option value="{{$id->id_program}}">{{ $id->nama}}</option>
#endforeach
</select>
Ajax Script
$(function() {
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN' : $('meta[name="csrf-token"]').attr('content')}
});
$(function(){
$('#id').on('change',function(){
number =$('#id').val();
console.log(number)
$.ajax({
type : 'POST',
url : "{{route('database.data',lcfirst($name))}}",
cache : false,
data:function(d){
d.number = number;
return d;
},
success: function(msg){
console.log('success')
},
})
})
})
});
Result (Error)
a. ( id_program = 1 ) Correct data output & Method Not Allowed error
b. ( id_program = 2 ) Incorrect data output & Method Not Allowed error
Thank you for the helps
Route::get('program/database/{database}', [DatabaseController::class,'data'])->name('database.data');
see the "get" key word? You are declare this route as a GET route, but your AJAX method:
$.ajax({
type : 'POST',
url : "{{route('database.data',lcfirst($name))}}",
....
is a POST request.
The solution is:
if your request only GET some data (no create, no delete, no update,... any data), then $.ajax({ type : 'GET', ....
if your request do modify data, then Route::post('program....

Returning an array from DB query as JSON and then putting the contents into list elements with jQuery

I have a commenting system I am working on thats is aiming to be like instagrams system.
Currently, I show the last 3 items in a PHP foreach and also have a 'show all button'.
My aim is then that button gets clicked and calls a function which then returns all the comments as an array. I then would need to .prepend() this array as list elements.
Normally an AJAX call to fetch data is fine. But in the past I have only retuned one line values.
I am using Laravel so my function to fetch would be something like:
public function fetch() {
DB:: // SELECT ALL COMMENTS
$commentsArray = array();
foreach ($comments as $comment) {
$commentsArray = (array('commentusername', 'comment'));
}
return Response::json(array(
'success' => true,
'comments' => $commentsArray,
200)
);
}
And then in my jQuery call:
if (data.success) {
$(".comments_"+id).prepend("<li><b>USERNAME:</b> Comment</li>");
}
That prepend woulds as I want, but I need to learn how I should be correctly creating the array, and then how I can loop through them and create the list elements in jQuery.
Note, that PHP function is written here and untested etc.
Thanks.
First, use array_map to get an array of the format you want:
public function fetch() {
DB:: // SELECT ALL COMMENTS
$commentsArray = array_map(function($comment){
return array(
'username' => $comment->commentusername,
'comment' => $comment->comment
);
}, $comments);
return Response::json(array(
'success' => true,
'comments' => $commentsArray
));
}
(I changed commentusername to username for the output array. Also you don't need the 200 in your response)
Now this is what your response will look like:
{
success: true,
comments: [
{username: 'foo', comment: 'comment of foo'},
{username: 'foo', comment: 'comment of foo'}
]
}
Then in your javascript code, do this:
if (data.success) {
for(var i=0; i<data.comments.length; i++){
var comment = data.comments[i];
$(".comments_"+id).prepend("<li><b>"+comment.username+":</b> "+comment.comment+"</li>");
}
}
Also note that if you use HTTP status codes for errors, you can remove success: true and assume that if the response is 200 (ajax success callback) the request has been made successfully.
I could not understand your question, but i m gonna to show you, how you can get json response from script and then can parse that,
// script.php
<?php
$data = array(
array('User' : 'Tiger', 'Comment' : 'Any comment,, '),
array('User' : 'John', 'Comment' : 'Tiger is nice guy !!')
); // In reality data will fetch from Db
header('Content-Type: application/json'); // must be set, and no space between ...pe and ':'
echo json_encode($data);
?>
client_side.js
$.get('script.php', function(data) {
for(i = 0; i < data.length; i++){
$(".comments_"+id).prepend("<li><b>USERNAME :</b> " + data[i].User + " <b> Comment :</b> " + data[i].Comment + "</li>"); // You should use templete here
} // __prepending comments
}, 'json');
Thanks :)
First of all, you need to add your arrays to an array. As you do, you are always just overwrite your variable:
$commentsArray[] = (array('commentusername', 'comment'));
add a [] after your name of variable.
And then in the jQuery:
$.each(data, function(idx, obj) {
$(".comments_"+id).prepend("<li><b>USERNAME:" + obj.commentusername + ", </b> Comment</li>" + obj.comment);
});
NOTE: Don't forget to check and change your id in the loop.

Sending json to symfony controller

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.

jquery ajax not parsing json data from php

I'm facing a strange problem for the last 10 hours and its really very annoying. The problem is with jquery printing json data from php. The php script is running fine, but when the ajax call returns in complete: event i'm not getting any valid otput.
here is the jquery code::
list_choice = "A";
content_choice = "Artists"; //globals to store default value
$(document).ready(function() {
$('.list-nav > a').click(function() {
var ltext = $(this).text();
list_choice = ltext;
console.log(ltext+" <------> ");
$.ajax({
url: 'retrieveFileFront.php',
data: {type: content_choice, navtext: list_choice},
type: 'POST',
dataType: 'json',
complete: function(data) {
console.log(data['message']['Album_Name']);
}
});
return false;
});
});
i had to use complete: event as success: didn't worked at all. Atleast i'm getting some sort of output from the complete: event, although its giving undefined or [object][Object] which is totally ridiculous.
here is the retrieveFileFront.php:
<?php
require './retrieveFiles.php';
$type = $_POST['type'];
$nav_text = $_POST['navtext'];
$ret_files = new retrieveFiles($type, $nav_text);
$data = $ret_files->retFiles();
if ($data['success'] == FALSE) {
$data = array('success' => FALSE, 'message' => 'Sorry an Error has occured');
echo json_encode($data);
} else {
echo json_encode($data);
}
?>
and here is the /retrieveFiles.php
<?php
class retrieveFiles {
public $content_type;
public $list_nav;
public $connection;
public $result;
public $result_obj;
public $tags_array;
public $query;
public $row;
public function __construct($type, $nav_text) {
$this->content_type = $type;
$this->list_nav = $nav_text;
}
public function retFiles() {
#$this->connection = new mysqli('localhost', 'usr', 'pass', 'data');
if(!$this->connection) {
die("Sorry Database connection could not be made please try again later. Sorry for the inconvenience..");
}
if ($this->content_type == "Artists") {
$this->query = "SELECT album_name, album_art FROM album_dummy NATURAL JOIN album_images_dummy WHERE artist_name LIKE '$this->list_nav%'";
try {
$this->result = $this->connection->query($this->query);
$this->row = $this->result->fetch_row();
if (isset($this->row[0]) && isset($this->row[1])) {
$this->tags_array = array("success" => true, "message" => array("Album_Name" => $this->row[0], "Album_Art" => $this->row[1]));
return $this->tags_array;
}
} catch (Exception $e) {
echo 'Sorry an Error has occurred'.$e;
return false;
}
}
}
}
?>
I'm getting a 200 response in console in firebug, which indicates that its running okay.
<!DOCTYPE HTML>
{"success":true,"message":{"Album_Name":"Streetcleaner","Album_Art":"\/var\/www\/html\/MusicLibrary\/Musics\/1989 - Streetcleaner\/folder.jpg"}}
Now this is making me even more confused as i can see that the json is formatted properly. Please provide any sort of suggestion on how to solve this problem.
Thanks in advance..
JSON encoded data is usually not sent like
data['message']['Album_Name']);
But rather like:
data.message.Album_Name;
You're calling your results the wrong way. These are not associative arrays anymore but are now objects, as the name JSON (JavaScript Object Notation) suggests.
You need to parse the json response using
data = $.parseJSON(data)
Use success event instead of complete in ajax and we can able to parse JSON encoded data in javascript/jQuery by using JSON.parse
well after a long period of trauma, i finally found a solution, turns out that i needed to parse the response text and then access the objects, individually.
Here is the working code
list_choice = "A";
content_choice = "Artists"; //globals to store default value
$(document).ready(function() {
$('.list-nav > a').click(function() {
var ltext = $(this).text();
list_choice = ltext;
console.log(ltext+" <------> ");
$('#loading').css('visibility', 'visible');
$.ajax({
url: 'retrieveFileFront.php',
data: {type: content_choice, navtext: list_choice},
type: 'POST'
dataType: 'json',
complete: function(data) {
var res = data.responseText;
res = res.replace(/<!DOCTYPE HTML>/g, "");
res = res.trim();
console.log(res);
var arr = JSON.parse("[" + res +"]"); //needed to parse JSON object into arrays
console.log(arr[0].message.Album_Name);
console.log(arr[0].message.Album_Art);
$('#loading').css('visibility','hidden');
}
});
return false;
});
This works fine and gives the desired response. Anyways thanks for the help, guys.

JSON returned as individual string and not objects

I am using Codeigniter and trying to use the jQuery autocomplete with it. I am also using #Phil Sturgeon client rest library for Codeigniter because I am getting the autocomplete data from netflix. I am return correct JSON and I can access the first element with
response(data.autocomplete.autocomplete_item[0].title.short);
but when I loop through the results
for (var i in data.autocomplete.autocomplete_item) {
response(data.autocomplete.autocomplete_item[i].title.short)
}
it acts like a string. Lets say the result is "Swingers", it will return:
Object.value = s
Object.value = w
Object.value = i
and so on.
the js:
$("#movies").autocomplete({
source: function(request, response) {
$.ajax({
url: "<?php echo site_url();?>/welcome/search",
dataType: "JSON",
type:"POST",
data: {
q: request.term
},
success: function(data) {
for (var i in data.autocomplete.autocomplete_item) {
response(data.autocomplete.autocomplete_item[i].title.short);
}
}
});
}
}).data("autocomplete")._renderItem = function(ul, item) {
//console.log(item);
$(ul).attr('id', 'search-autocomplete');
return $("<li class=\""+item.type+"\"></li>").data( "item.autocomplete", item ).append(""+item.title+"").appendTo(ul);
};
the controller:
public function search(){
$search = $this->input->post('q');
// Run some setup
$this->rest->initialize(array('server' => 'http://api.netflix.com/'));
// set var equal to results
$netflix_query = $this->rest->get('catalog/titles/autocomplete', array('oauth_consumer_key'=>$this->consumer_key,'term'=> $search,'output'=>'json'));
//$this->rest->debug();
//$json_data = $this->load->view('nice',$data,true);
//return $json_data;
echo json_encode($netflix_query);
}
the json return
{"autocomplete":
{"autocomplete_item":[
{"title":{"short":"The Strawberry Shortcake Movie: Sky's the Limit"}},
{"title":{"short":"Futurama the Movie: Bender's Big Score"}},
{"title":{"short":"Daffy Duck's Movie: Fantastic Island"}}
...
any ideas?
thanks.
there are some console logs with the return
the url
in, as you've noticed, doesn't do what you'd like with arrays. Use $.each
As far as I know, for (property in object) means that you want to access each of its properties rather than accessing them via the index. If you want to access them via the index, you probably want to use the standard for loop.
for (i = 0; i <= 10; i++) {
response(data.autocomplete.autocomplete_item[i].title.short);
}
or if you still want to use your code, try this:
for (i in data.autocomplete.autocomplete_item) {
response(i.title.short);
}
I haven't test them yet but I think you have the idea.
ok I figured out the correct format that I need to send to the autocomplete response method:
the view
$("#movies").autocomplete({
minLength: 2,
source: function(request, response) {
$.post("<?php echo base_url();?>welcome/search", {q: request.term},
function(data){
//console.log(data);
response(data);
}, 'json');
}
});
the controller:
$search = $this->input->post('q');
// Run some setup
$this->rest->initialize(array('server' => 'http://api.netflix.com/'));
// Pull in an array
$netflix_query = $this->rest->get('catalog/titles/autocomplete', array('oauth_consumer_key'=>$this->consumer_key,'term'=> $search,'output'=>'json'),'json');
$json = array();
foreach($netflix_query->autocomplete->autocomplete_item as $item){
$temp = array("label" => $item->title->short);
array_push($json,$temp);
}
echo json_encode($json);
what was needed was to send back to the view an array of objects. Thank you guys for all your answers and help!!

Categories