passing JSON data and getting it back - javascript

I'm new to passing objects through AJAX, and since I am unsure of both the passing and retrieving, I am having trouble debugging.
Basically, I am making an AJAX request to a PHP controller, and echoing data out to a page. I can't be sure I'm passing my object successfully. I am getting null when printing to my page view.
This is my js:
// creating a js filters object with sub arrays for each kind
var filters = {};
// specify arrays within the object to hold the the list of elements that need filtering
// names match the input name of the checkbox group the element belongs to
filters['countries'] = ["mexico", "usa", "nigeria"];
filters['stations'] = ["station1", "station2"];
filters['subjects'] = ["math", "science"];
// when a checkbox is clicked
$("input[type=checkbox]").click(function() {
// send my object to server
$.ajax({
type: 'POST',
url: '/results/search_filter',
success: function(response) {
// inject the results
$('#search_results').html(response);
},
data: JSON.stringify({filters: filters})
}); // end ajax setup
});
My PHP controller:
public function search_filter() {
// create an instance of the view
$filtered_results = View::instance('v_results_search_filter');
$filtered_results->filters = $_POST['filters'];
echo $filtered_results;
}
My PHP view:
<?php var_dump($filters);?>
Perhaps I need to use a jsondecode PHP function, but I'm not sure that my object is getting passed in the first place.

IIRC the data attribute of the $.ajax jQuery method accepts json data directly, no need to use JSON.stringify here :
data: {filters: filters}
This way, you're receiving your json data as regular key/value pairs suitable for reading in PHP through the $_POST superglobal array, as you would expect.

http://blog.teamtreehouse.com/beginners-guide-to-ajax-development-with-php
When you use ajax the page is not reloaded so the php variable isn't of use.
You may want to look for a tutorial to help. I put one at the beginning as I don't see how to format this on my tablet
you will need to json_encode your response as the tutorial shows
you may want to print to a log on the server when you are in the php function and make it world readable so you can access it via a browser
I like to use the developer tools in Chrome to see what is actually returned from the server

Related

Retrieve multiple variables from an AJAX call to jQuery

I have a PHP file that requests six rows from a database. I'm using an ajax call.
I want these six rows (multiple columns) to be passed through to my main file. I was unable to find a way to get these values to my main page except for posting them in html in the request file and posting this as a table on my main page.
I don't want them on the page in a plain table for everyone to be seen.
So not like this:
success: function(html) {
$("#display").html(html).show();
}
I always need six rows at the moment but could be more later on.
One of the ideas that I had was posting it as one long string and loading this into a variable, and then reading using explode or something a-like. Not sure if this is a good way to do this...
I am basically asking for ideas to expand my horizon.
I am still learning JavaScript and jQuery so I'd rather have a good explanation than a block of working code.
Thanks in advance!
PHP Side
This is a very simple process, which you may kick yourself after grasping ;) But once you do, it opens a world of possibilities and your mind will go crazy with ideas.
The first stage is you want to adjust your data that you will be returning to the ajax call. If you have a few rows of a few fields, you would do have something along these lines (could come from db, or assignments, whatever):
$rows = [];
$rows[] = array('thing'=>'value 1','something'=>'blah','tertiary'=>'yup');
$rows[] = array('thing'=>'value 2','something'=>'yadda','tertiary'=>'no');
$rows[] = array('thing'=>'value 3','something'=>'woop','tertiary'=>'maybe');
Now, to get this rows of data out to ajax, you do this one simple operation:
echo json_encode($rows);
exit; // important to not spew ANY other html
Thats all you really need to do on the PHP side of things. So what did we do? Well, we took a multidimensional array of data (usually representing what comes from a database), and encoded it in JSON format and returned it. The above will look like this to your browser:
[{"thing":"value 1","something":"blah","tertiary":"yup"},
{"thing":"value 2","something":"yadda","tertiary":"no"},
{"thing":"value 3","something":"woop","tertiary":"maybe"}]
It will have handled all escaping, and encoding of utf8 and other special characters. The joys of json_encode()!
JAVASCRIPT Side
This side is not as difficult, but theres some things to understand. FIrst off, lets get your jquery ajax call into shape:
<div id="rows"></div>
<script>
$("#your-trigger").on('click',function(e){
e.preventDefault(); // just stops the click from doing anything else
$.ajax({
type: "POST",
url: 'your_ajax.php',
data: { varname: 'value', numrows: '6' },// your sent $_POST vars
success: function(obj) {
// loop on the obj return rows
for(var i = 0; i < obj.length; i++) {
// build a div row and append to #rows container
var row = $('<div></div>');
row.append('<span class="thing">'+ obj[i].thing +'</span>');
row.append('<span class="details">'+
obj[i].something +' '+ obj[i].tertiary
+'</span>');
$("#rows").append(row);
}
},
dataType: 'json' // important!
});
});
</script>
So lets explain a few key points.
The most important is the dataType: 'json'. This tells your ajax call to EXPECT a json string to turn into an object. This object becomes what you define in the success function arg (which I named obj above).
Now, to access each specific data variable of each row, you treat it as an object. Array of rows, each row has vars named as you named them in PHP. This is where I have the for example to loop through the array of rows.
For example obj[0].thing refers to the first row of variable thing. The use of i lets you just go through all rows automatically based on length of the object. A few handy things in there.
You can build any html you wish from the returned object and values. I just showed how to setup a <div><span class="thing"></span><span class="details"></span></div> example row. You may want to use tables, or more complex setups and code.
To keep the return data from your ajax call, you can store it in a local or global variable like so:
<script>
var globalvar;
$....('click',function(e){
var localvar;
$.ajax(.... success: function(obj){
....
localvar = obj;
globalvar = obj;
....
});
});
</script>
Do what Frederico says above. Return json from your php and get in in jQuery using ajax call.
Something like this: http://makitweb.com/return-json-response-ajax-using-jquery-php/. Just skip step #3 and do what you need with received data in step #5 if you don't need it to be printed to html.

The file is emptied when I use file_put_contents

Main issue was solved in comments, although one of the bonus questions is still open and the other's solution could use some improvement
All of this takes place on a webhosting service, the folder structure is as follows:
The JavaScript and PHP files are in /public_html/, the JSON is in /public_html/data/.
In my JS code, I'm sending a POST request with some data for my JSON file:
console.log(objdata.buildings[0].coords);
var params = JSON.stringify(objdata);
if (objdata.buildings[0].coords != " "){
$.ajax({
type: "POST",
data: params,
url: "writecoords.php",
success: function(data){
console.log(params);
console.log(data);
console.log("AJAX success");
},
error: function(){
console.log("failed to send POST");
alert("error");
}
});
}
PHP file:
<?php
function debug_to_console($data){
if(is_array($data) || is_object($data))
{
echo("\n".json_encode($data));
} else {
echo("\n".$data);
}
}
$newJSON = json_decode(file_get_contents('php://input'));
debug_to_console($newJSON);
if (is_writable('data/strogi.json')) {
$a = file_put_contents('data/strogi.json', $newJSON);
if(! $a)
debug_to_console("Wrote nothing");
debug_to_console("PHP write success");
} else {
debug_to_console("PHP write failed");
}
?>
As you can see, I perform a check at every possible point to see if I'm actually processing non-empty data -- I log the value of the key in question, the AJAX request is sent only if it was changed, I log the data being sent and I log the data my PHP file receives and decodes.
I also check if the file is writable to avoid a possible permission problem, and only then I try to write to the file. The file comes out empty and I get the following outputs in console
params is my JSON object as a single line;
data is: my JSON object as a single line with line breaks before every new object and all cyrillic converted to \u format, "Wrote nothing!", "PHP write success";
"AJAX success"
If I check the strogi.json file after this, it's absolutely empty.
To rule out a problem with the format of passed JSON object, I tried writing to a simple test.txt file in the same directory as the .php, which turns out empty as well.
I tried using the method described here, but nothing changed.
I tried using a FTP upload (the method is pointed out somewhere in the comments here), and I got "No such file or directory" returned both for the strogi.json and test.txt files. I used both public_html/test.txt and test.txt as file name.
I tried using the combination of locks FILE_APPEND | LOCK_EX, and no changes happen to either of the files.
My questions are:
Why?
Can a different solution be used if all of this is taking place in the .done() callback for $.getJSON() called on the same file?
Follow-up question worthy of a separate section:
coords is a 3-dimensional array
[
[[x1,y1],[x2,y2],...]]
]
where the external array contains up to two arrays. The first array contains points of the external polygon and (if present) second array contains points of the internal polygon that serves as a cutout.
The code in question is an attempt to make submitting the coords array to strogi.json work for at least one object.
What I'm trying to do, in general, is
$.getJSON() the data/strogi.json file
go through the buildings[] array of objects inside it in the .done()
callback
for each object, check if "coords" is " " (default value)
If it is, a constructor is called to build a polygon using a map API, and when construction is finished, $.ajax is used to submit coords extracted through one of API's functions.
As of now, I'm submitting the whole JSON object, because I'm only working with one of the inner objects, but I imagine resubmitting the whole thing is excessive with multiple objects presented.
Is there a way to pass objdata.buildings[i].coords with the index i to PHP to change the "coords" key value in JSON for a certain buildings[i] object?
Do I need to make any changes to the way I'm processing data to make my JSON valid upon further reads? I assume I'd have to change the "coords" value from [[[x1,y1],[x2,y2]]] (the way it's passed now) to something like this (pastebin because there's no code formatting even though I'm using the 4 space indent)
for it to work, right? How do I do that? partly solved by going through the array in JS with two for() loops and applying toString() to every coordinate, there's gotta be a better way

Do Ajax calls and maintain class structure

Hello I am wondering what is the common method of structuring ajax and php?
I am doing a website/application which have a lot of ajax calls. Also I do have a class in php I use for my main php code for keeping track of the user.
When I do ajax calls with jquery to smaller php files I need to re-declare my object I have in other files. I want the object that I have in my "main" php file. What is a good method to get the same object? Right now I am using jquery to pass the values from a div element (which comes from the object previously).
I feel this is not the best practice. I want to do it structured.
Example: I store the user session in User.
I have a button a user can click to get some information about his data. For this I have a jquery ajax call which sends and retrieves data for display. In that php file I do have to redo everything again, even if I include the class file, because the object is declared elsewhere.
Example. User can create lists in this kind of way.
I have the main index file which includes this file of new User. This type of stuff.
$user = new User();
if($_SESSION["user_connected"])
{
$user_profile = $twitter->getUserProfile();
$displayname = $user_profile->displayName;
}
$user->username = $displayname;
// Also user has an array of lists
jQuery
$('#createlistform').submit(function(event)
{
var newlistname = $('#listname').val();
var createlistRequest = $.ajax(
{
url: "ajax/ajax_add_list.php",
dataType: "html",
type: "POST",
data: {
listname: newlistname
}
}
);
the ajax_add_list file ajax is calling below. Now what I do to get this work is sending the username through as a data parameter to the php file from picking it up by $('#username').text() then set a new user with that username. It is not in the example now... but you get the point I think.
include_once("../user.class.php");
$theUser = new User();
if(class_exists('User'))
{
echo "yes class exists";
$newlistname = $_POST['listname'];
$theUser->createList($newlistname);
}
I wish I could get the same User object that was defined in my index file. I don't wanna create a new one. Although if this is how people do it when they have ajax I'll do it. I just want to know how you usually go by when dealing with different files here and there with javascript getting data from various places, while still maintaining a good structure with class and object.

return a PHP object to an ajax call

I'm learning PHP OOP, and getting used to all of these objects.
When I create an object in a PHP file called via an $.ajax function, I want to deliver the answer back. But how am I supposed to send back the object to my ajax call ? Before OOP, I was putting everything into an array, then json_encode() the array, and everything worked perfectly. How to adapt this using OOP?
Thanks a lot for your answers
Romain
Example:
On the client side
$.ajax(
{
url:"test.php",
type:"POST",
dataType:"json",
success:function(json)
{
// json into template
}
});
On the server side: test.php
require_once("bdd.php");
function loadClass($class)
{
require $class.".class.php";
}
spl_autoload_register('loadClass');
$PersonneM = new PersonneManager($db);
$perso = $PersonneM->get("123456");
$perso = serialize($perso); // ????????????
header('Content-type: application/json');
echo json_encode(array("result",$perso));
either use serialize or __toString to create a JSON-representation of your data that you can send down the tube. You will not be needing an extra array around your object.
However, there is an error in some JSON parsers/interpreters that can mess with your data when not wrapped in an array. But I haven't heared anything of this issue since a couple of years so you should be safe

Accessing JSON values with a variable

I'm trying to access JSON data with jQuery and grab a specific set of values based on a variable. I've done this before using [] but for some reason I can't figure out what is going wrong this time.
My JSON file (being read in by getJSON, and named jsonmaker.php) looks like this:
{"0107001":{"label":"Canada","x":"0","y":"0.34"},"0107002":{"label":"USA","x":"-0.16","y":"0.53"}}
I then have a function which is essentially this:
function addAttrib(attrib) {
$.getJSON("jsonmaker.php", function(data) {
alert(data[attrib].label);
}
}
But it keeps returning undefined. Any idea what I'm doing wrong? I've checked to make sure the var going to attrib is 0107001, no problems there.
Also, I know my JSON file is a php file so I could filter what's returned to match the attrib value, but I'm looking to develop something that can run purely on HTML and JS, so I could just pack the JSON file for the project and take it with me. No need for a web server w/ PHP etc.
The data access itself works for me:
var data = {"0107001":{"label":"Canada","x":"0","y":"0.34"},"0107002":{"label":"USA","x":"-0.16","y":"0.53"}};
var attrib = "0107002";
alert(data[attrib].label); // USA
Make sure that attrib remains untouched between the moment you call addAttrib() and the moment when the AJAX request completes and your anonymous callback function gets called.
Update: is this your real code? You have at least one syntax error:
function addAttrib(attrib) {
$.getJSON("jsonmaker.php", function(data) {
alert(data[attrib].label);
}); // <- Please note missing ");"
}
In my experience, $.getJSON() doesn't always return an object. Depending on the MIME type that the server returns along with the JSON, you might end up with a string instead of an object. Check what data contains. If it's a string, you must manually parse it using eval() (old style) or JSON.parse() (new browsers only).
try to list all properties from data, to have sure the data is being returned:
for (var p in data){
if (data.hasOwnProperty(p){
alert(data[p]);
}
}
It's not your solution but with this you can know how your data is coming.

Categories

Resources