JQuery (Mobile) /Ajax Undefined returned variable - ajax

Despite many questions regarding this I cannot seem to find some code that works for my situation, every time I run this code I end up with an undefined variable instead of the desired returned JSON.
My AJAX code is:
$.ajax({
data: {"serial":account},
url: 'http://127.0.0.1/MobilePHP/findCustomerName.php',
dataType: 'json',
success: function(data){
window.alert(data);
}
});
And my PHP code is:
<?php
header("Access-Control-Allow-Origin: *");
header('Content-type: application/json');
include 'dbConfig.php';
include 'connectDB.php';
//$account = $_POST['serial'];
$account = 14;
$sth = mysql_query("SELECT customer_name AS Name FROM customer_details WHERE auto_id = $account ");
$rows = array();
while($r = mysql_fetch_assoc($sth)) {
$rows ['CustomerName'][] = $r;
}
echo json_encode($rows);
include 'closeDB.php';
?>
And my JSON from my console is:
{"CustomerName":[{"Name":"Tullaroan"}]}
I am really unsure of why I cannot access these variables as it seems to return the right JSON on the console.

Inside the success function, data is an object with a single property: CustomerName. To access that, you use data.CustomerName. That property is itself an array, so you'll need to access elements inside it using their index.
In your example, you have a single object in the array, so to access that object you'd do data.CustomerName[0]. That object also has a single property: Name, so to get the actual name out you'd do: data.CustomerName[0].Name, which would return "Tullaroan".
It might be easier to visualise the breakdown of the data object like this:
data = {"CustomerName":[{"Name":"Tullaroan"}]}
data.CustomerName = [{"Name":"Tullaroan"}]
data.CustomerName[0] = {"Name":"Tullaroan"}
data.CustomerName[0].Name = "Tullaroan"

Related

Laravel & Ajax return array response no parsing

Currently I'm trying to pull some data via ajax and I'm not getting the data to appear properly.
In my ajax call I have this:
$.ajax({
url:"{{ route('pricing.fetch') }}",
method:"POST",
data:{select:select, value:value, _token:_token, dependent:dependent, productId:productId},
success:function(result)
{
$("ul[data-dependent='quantity']").html(result);
This works as expected. The problem is I'm trying to return data from different tables in my db. So I'm trying to do it by changing my result in ajax to this.
$("ul[data-dependent='quantity']").html(result.productQuantities);
The reason for me wanting to do this is because I have multiple drop downs I need. So I would also like to do another one like this:
$("ul[data-dependent='quantity']").html(result.productPaperStock);
my controller code is like this:
$data = Product::with(['productQuantity', 'productPaperstock'])->where('ID', $productId)->first();
// pull the quantity for this product
$productQuanties = $data->productQuantity;
$productPaperStock = 'hello';
$output = '';
foreach($productQuanties as $productQuantity)
{
$output .= "<li><span>" . $productQuantity->quantity_name . "</span></li>";
}
return response()->json["productQuanties" => $productQuanties, "productPaperStock" => $productPaperStock]);
I'm not sure what I'm doing wrong but using this example above I get a 500 error.
You need to set dataType: json option in your ajax request, and then in your controller, you can return json response.
Also, you are missing the starting brace in your controller code. The correct code is
return response()->json(["productQuanties" => $productQuanties, "productPaperStock" => $productPaperStock])
(Note that ...storage/logs/laravel.log is an awesome place to get insights into what's screwing your app:))

simple json response with cakephp

I trying to pass some json to a controller in cakePHP 2.5 and returning it again just to make sure it is all going through fine.
However I getting no response content back. Just a 200 success. From reading the docs I am under the impression that if I pass some json then the responseHandler will the return json as the response.
Not sure what I am missing.
Data being passed
var neworderSer = $(this).sortable("serialize");
which gives
item[]=4&item[]=3&item[]=6&item[]=5&item[]=7
appController.php
public $components = array(
'DebugKit.Toolbar',
'Search.Prg',
'Session',
'Auth',
'Session',
'RequestHandler'
);
index.ctp
$.ajax({
url: "/btstadmin/pages/reorder",
type: "post",
dataType:"json",
data: neworderSer,
success: function(feedback) {
notify('Reordered pages');
},
error: function(e) {
notify('Reordered pages failed', {
status: 'error'
});
}
});
PagesController.php
public function reorder() {
$this->request->onlyAllow('ajax');
$data = $this->request->data;
$this->autoRender = false;
$this->set('_serialize', 'data');
}
UPDATE:
I have now added the following to the routes.php
Router::parseExtensions('json', 'xml');
and I have updated my controller to
$data = $this->request->data;
$this->set("status", "OK");
$this->set("message", "You are good");
$this->set("content", $data);
$this->set("_serialize", array("status", "message", "content"));
All now works perfectly.
A proper Accept header or an extension should to be supplied
In order for the request handler to be able to pick the correct view, you need to either send the appropriate Accept header (application/json), or supply an extension, in your case .json. And in order for extensions to be recognized at all, extension parsing needs to be enabled.
See http://book.cakephp.org/...views.html#enabling-data-views-in-your-application
The view only serializes view vars
The JSON view only auto-serializes view variables, and from the code you are showing it doesn't look like you'd ever set a view variable named data.
See http://book.cakephp.org/...views.html#using-data-views-with-the-serialize-key
The view needs to be rendered
You shouldn't disable auto rendering unless you have a good reason, and in your case also finally invoke Controller:render() manually. Currently your action will not even try to render anything at all.
CakeRequest::onlyAllow() is for HTTP methods
CakeRequest::onlyAllow() (which btw is deprecated as of CakePHP 2.5) is for specifying the allowed HTTP methods, ie GET, POST, PUT, etc. While using any of the available detectors like for example ajax will work, you probably shouldn't rely on it.
Long story short
Your reorder() method should look more like this:
public function reorder() {
if(!$this->request->is('ajax')) {
throw new BadRequestException();
}
$this->set('data', $this->request->data);
$this->set('_serialize', 'data');
}
And finally, in case you don't want/can't use the Accept header, you need to append the .json extension to the URL of the AJAX request:
url: "/btstadmin/pages/reorder.json"
and consequently enable extension parsing in your routes.php like:
Router::parseExtensions('json');
ps
See Cakephp REST API remove the necessity of .format for ways to use the JSON view without using extensions.
Output your json data
public function reorder() {
$this->request->onlyAllow('ajax');
$data = $this->request->data;
$this->autoRender = false;
$this->set('_serialize', 'data');
echo json_encode($data);
}

Loading page dynamically from database via id in controller

I am trying to load a page dynamically based on the database results however I have no idea how to implement this into codeigniter.
I have got a controller:
function history()
{
//here is code that gets all rows in database where uid = myid
}
Now in the view for this controller I would like to have a link for each of these rows that will open say website.com/page/history?fid=myuniquestring however where I am getting is stuck is how exactly I can load up this page and have the controller get the string. And then do a database query and load a different view if the string exsists, and also retrieve that string.
So something like:
function history$somestring()
{
if($somestring){
//I will load a different view and pass $somestring into it
} else {
//here is code that gets all rows in database where uid = myid
}
}
What I don't understand is how I can detect if $somestring is at the end of the url for this controller and then be able to work with it if it exists.
Any help/advice greatly appreciated.
For example, if your url is :
http://base_url/controller/history/1
Say, 1 be the id, then you retrieve the id as follows:
function history(){
if( $this->uri->segment(3) ){ #if you get an id in the third segment of the url
// load your page here
$id = $this->uri->segment(3); #get the id from the url and load the page
}else{
//here is code that gets all rows in database where uid = myid and load the listing view
}
}
You should generate urls like website.com/page/history/myuniquestring and then declare controller action as:
function history($somestring)
{
if($somestring){
//I will load a different view and pass $somestring into it
} else {
//here is code that gets all rows in database where uid = myid
}
}
There are a lot of ways you can just expect this from your URI segments, I'm going to give a very generic example. Below, we have a controller function that takes two optional arguments from the given URI, a string, and an ID:
public function history($string = NULL, $uid = NULL)
{
$viewData = array('uid' => NULL, 'string' => NULL);
$viewName = 'default';
if ($string !== NULL) {
$vieData['string'] = $string;
$viewName = 'test_one';
}
if ($uid !== NULL) {
$viewData['uid'] = $uid;
}
$this->load->view($viewName, $viewData);
}
The actual URL would be something like:
example.com/history/somestring/123
You then know clearly both in your controller and view which, if any were set (perhaps you need to load a model and do a query if a string is passed, etc.
You could also do this in an if / else if / else block if that made more sense, I couldn't quite tell what you were trying to put together from your example. Just be careful to deal with none, one or both values being passed.
The more efficient version of that function is:
public function history($string = NULL, $uid = NULL)
{
if ($string !== NULL):
$viewName = 'test_one';
// load a model? do a query?
else:
$viewName = 'default';
endif;
// Make sure to also deal with neither being set - this is just example code
$this->load->view($viewName, array('string' => $string, 'uid' => $uid));
}
The expanded version just does a simpler job at illustrating how segments work. You can also examine the given URI directly using the CI URI Class (segment() being the most common method). Using that to see if a given segment was passed, you don't have to set default arguments in the controller method.
As I said, a bunch of ways of going about it :)

Codeigniter can't use this->uri->segment(3) as value in function

Why this code is ok
$this->sch_teacher_id = $this->ion_auth->user_by_username("vika")->row()->id;
But this doesn't work?
$this->sch_teacher_id = $this->ion_auth->user_by_username($this->uri->segment(3))->row()->id;
My url is domain:8888/admin_schedule/teacher/vika
route.php contains
$route['admin_schedule/teacher/(:any)'] = "admin_schedule/index/$1";
I use code lines in function __construct(), and the result of it use in another controller function, because 3 functions use this result. If I move this code in one of this functions and use $this->uri->segment(3) then I get not 'vika's lessons, but my own lessons, so
public function user_by_username($username = FALSE)
{
$this->trigger_events('user');
//if no id was passed use the current users id
$username || $username = $this->session->userdata('username');
$this->limit(1);
$this->where($this->tables['users'].'.username', $username);
$this->users();
return $this;
}
works good. But $this->uri->segment(3) if use it as parameter in user_by_username function, doesn't work!
page generated next way:
controller admin_schedule have function index which render view index.php.
And in that view I use javascript, that call another function from admin_schedule controller = get_schedule_db_recurring_events_on_daysweek such way:
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
backgroundColor: 'red',
}
and in controller
function get_schedule_db_recurring_events_on_daysweek()
{
$start = date('Y-m-d H:i', $this->input->get('start'));
$end = date('Y-m-d H:i', $this->input->get('end'));
$sch_teacher_id = $this->uri->segment(3); // <--- this doesn't work, but $sch_teacher_id = 111 works perfectly
$result=$this->Schedule_model->get_schedule_recurring_events_on_daysweek($start, $end, $sch_teacher_id);
$count=count($result);
if($count>0){
echo json_encode($result);
}
}
Please, help understand this problem.
I can't remember the reason - it's just CI quirk you have learn to accept - you can't use $this->uri->segment(3) etc as an argument directly, you will need to assign it and then pass that as #almix suggested for his sanity test.
At-least I have also always had trouble using it directly as an argument - tho I will be happy for anyone to correct me!
I solved my problem!
Think that something goes wrong because of ajax calls. So when I code in controller
function __construct()
{
parent::__construct();
...
$this->sch_teacher_row = $this->ion_auth->user_by_username($this->uri->segment(3))->row();
$this->data['sch_teacher_id'] = $this->sch_teacher_row->id;
$this->data['subtitle'] = $this->sch_teacher_row->username;
}
Next I have the right value ('vika'), or to be more precise vika's id ('911') in view file but not in other function of my controller. But I can pass this value now (sch_teacher_id) from the view to this controller with jQuery $.ajax option data:
eventSources: [
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
type: 'GET',
data: {sch_teacher_id: sch_teacher_id},
backgroundColor: 'red',
}
],
And next (on the other side of the mountain) catch this GET parameter and kick it to the model function:
function get_schedule_db_recurring_events_on_daysweek()
{
...
$sch_teacher_id_from_view = $this->input->get('sch_teacher_id');
$result=$this->Schedule_model->get_schedule_recurring_events_on_daysweek($start, $end, $sch_teacher_id_from_view);
...
}
And it is all the breakdance.

Codeigniter: how to foreach in javascript with a returned array

I need to loop through a returned array in javascript but it doesn't work, it will loop through each letter of the word array instead of looping throught the value.
this is the javascript code
$.ajax({
url: "<?php echo site_url('home/getsubcats'); ?>",
type: 'POST',
data: form_data,
success: function(msg)
{
for ( var i in msg )
{
alert( msg[i] );
}
//$('#main_content').html(msg);
}
});
and this is the controller (it get's the correct data so the query is not the problem);
function getsubcats()
{
$this->load->model('site_model');
if ($this->input->post('ajax')):
$catid = $this->input->post('id');
return $this->site_model->getSubCats($catid);
endif;
}
You might have to add returnType: 'json' to your $.ajax option object if your code returns JSON.
If your code loops over single characters it means msg is a string and not an array.
Additionally, use for(var i = 0; i < msg.length; i++) as for in loops will also include inherited attributes - so when using javascript frameworks which extend Object.prototype or Array.prototype you might run into trouble.
You are most likely iterating on a string response, not an Array. I don't think jQuery makes the conversion automatically.
I'm not familiar with CodeIgniter, but when you return getSubCats(), is the result automatically encoded into JSON? Because if not, you must encode it before sending it to the client.
Use the net panel of Firebug or the Resources tab in Chrome to inspect the actual response.

Resources