I am using the following code to make a request to a PHP script:
$.ajax({
method: "POST",
url: "myAPI.php",
data: {
orderById: 2,
action: 'returnStuff',
},
success: function(data){
$.each(data.data, function(key, value) {
var $targetToMove = $('.shape.'+value.attr_name);
//if element already exists on page, move it to the end of the container
if($('.'+value.xml_name).length){
$('.container').append($targetToMove);
}
});
}
});
Here is a simplified example of my return data
{"data":{"0":{"id":"1","name":"This","color":"blue"},
"1":{"id":"2","name":"That","color":"red"},
"2":{"id":"3","name":"whatever","color":"blue"}}}
If the orderById equals 1, the data is returned numerically from lowest to highest by the id. If it equals 2 it is returned numerically from highest to lowest like this:
{"data":{"0":{"id":"3","name":"whatever","color":"blue"},
"1":{"id":"2","name":"That","color":"red"},
"2":{"id":"1","name":"This","color":"blue"}}}
The idea is that the API returns the data in the order I want, then on success in the ajax call, the elements are re-arranged on the page in the order of the returned data object.
This works how I intend in Firefox, but in Chrome, whenever I console log the data on success, the order is always the same, despite the console indicating the response from my API is in the correct order.
What am I missing? I can't tell if this is a caching issue or if I am just overlooking something in my javascript.
Object properties order is not guaranteed in JavaScript. You would rather use Array for that
Format you json to look like this:
{"data":[{"id":"3","name":"whatever","color":"blue"},{"id":"2","name":"That","color":"red"},{"id":"1","name":"This","color":"blue"}]}
Related
I am struggling with getting data from WFS in my GeoServer. I want to get specific properties from the JSON returned by WFS and use it in my html page filling a table. I have read lots of posts and documentation but I can't seem to make it work. I have:
(a) changed the web.inf file in my geoserver folder to enable jsonp
(b) tried combinations of outputFormat (json or text/javascript)
(c) tried different ways to parse the JSON (use . or [], JSON.parse or parseJSON etc),
(d) used JSON.stringify to test whether the ajax call works correctly (it does!!)
but, in the end, it always returns undefined!!
function wfs(longitude, latitude){
function getJson(data) {
var myVar1=data['avgtemp1'];
document.getElementById("v1").innerHTML = myVar;
}
var JsonUrl = "http://88.99.13.199:8080/geoserver/agristats/wfs?service=wfs&version=2.0.0&request=GetFeature&typeNames=agristats:beekeeping&cql_filter=INTERSECTS(geom,POINT(" + longitude + " " + latitude + "))&outputFormat=text/javascript&format_options=callback:getJson";
$.ajax({
type: 'GET',
url: JsonUrl,
dataType: 'jsonp',
jsonpCallback:'getJson',
success: getJson
});
}
wfs(38, 23);
Could you please help me?
You are close to it. First, you have a typo in the variable name you are writing (myVar1 vs myVar). Secondly, your function is receiving a Json object, so you must dive into its structure. First you get the features, then the 1st one, then the property array, then the property of your choice.
I suggest you read a tutorial on Json Objects, as you will surely want to loop through properties/items, validate they are not null etc.
function getJson(data) {
var myVar1=data.features[0].properties['avgtemp1'];
document.getElementById("v1").innerHTML = myVar1;
}
At last, don't forget to use the debugger in your favorite browser. put a breakpoint in your function and check the structure and content of data.
I have a php file with a lot of checkboxes on the left hand side. I extract the values via javscript and pass them into an array. Which works just fine. I would like to pass then this array via Ajax to PHP in order to mess around with the values and create SQL-statements out of them.
$(document).ready(function(e) {
$('#getSelectedValues').click(function() {
var chkBoxArray = [];
$('.graphselectors:checked').each(function() {
chkBoxArray.push($(this).val());
});
for (var i = 0; i < chkBoxArray.length; i++) {
console.log(i + " = " + chkBoxArray[i]);
}
$.ajax({
url: 'index.php', // (1)
type: 'POST',
dataType:'json',
data: chkBoxArray, //(2)
success: function(data){
console.log(data.length);
console.log(data);
}
});
});
});
Several questions:
(1) what file name do I need to add here? The origion or the target?
(2) I have numerous ways of this: serialization, with these brackets {}, and so on. How to get it done right?
An error that I get is the following:
Notice: Undefined index: data in graph.php
That makes me wondering a bit, because it clearly shows no data is being send.
var_dumps on $_POST and $_SERVER offer these results:
array(0) { }
array(0) { }
which is somewhat unsatisfying.
Where am I doing things wrong? The only puzzling aspect is the ajax, all other stuff is not much of an issue.
The site is supposed to work in the following way:
Page -> Checkbox(clicked) -> Button -> result (ajax) -> PHP fetches result -> SQL DB -> PHP gets DB result -> fetch result (ajax) -> jslibrary uses result for something.
1- You need to point your ajax to the script that will use the data you are sending. I would not recommend to point to index.php, since you'll need to add a if statement checking if there is data on $_POST that is exactly what your're expecting, otherwise it will return the same page that you're in (considering that you are in index.php and is making a request to index.php). A point to consider. Since it is a whole request and it's not a method call to actually return something to your page you need to echo things. That said, consider also to set header('Content-Type: application/json') then, since you're expecting dataType: 'json', echo json_encode($objectorarray);
2- Since you're sending a Javascript array to PHP, it can't interpret correctly the structure, that is why you should use JSON.stringify(chkBoxArray) before sending it. But just setting it on data attribute would send the number of checkboxes you selected as values to POST, so consider to data: {myCheckboxValues: JSON.stringify(chkBoxArray)}
In your PHP script, considering all the security measures to take, you can $foo = json_decode($_POST['myCheckboxValues']);
Well, of course you need to pass the target page as url in your ajax call. It can't guess which file should process the data.
As for the data property. You need to give your data a name.
data: {
something: "something"
}
Becomes: $_POST['something']. (value: something)
$.ajax({
url: 'target.php', // (1)
type: 'POST',
dataType:'json',
data: { data: chkBoxArray }, //(2) Now $_POST['data'] will work
success: function(data){
console.log(data.length);
console.log(data);
}
});
I'm calling the below function after the data from an ajax call is returned. It performs the first console.log() which contains the data from the ajax call. But the each() loop iterating through - response, does not console.log anything.
primaSaveOrder.prototype = {
start: function(response){
console.log(response)
$j('#primaId').val('');
$j('#dialog').closest('.ui-dialog-content').dialog('close');
$j.each(response['billing'], function(i, val) {
console.log(response['billing'][i])
});
},
}
I don't think my code is too wrong though because if I manually create a variable in the console equal to the output of - console.log(response) and then run the -
$j.each(response['billing'], function(i, val) {
console.log(response['billing'][i])
});
it works. What I would prefer to run is $j('#' + i).val(response['billing'][i]) instead of console.log(response['billing'][i].
This also works if I do it directly in the browser but not in the file. I assume it's related but I can't figure out how to fix it.
this is an example of what i am iterating with some data changed for privacy
{"billing":{"order-billing_address_firstname":"test","order-billing_address_lastname":"test","order-billing_address_street0":"6 test","order-billing_address_street1":"test","order-billing_address_city":"","order-billing_address_country_id":"GB","order-billing_address_region":"","order-billing_address_postcode":"16","order-billing_address_telephone":"","order-billing_address_vat_id":"","order-billing_address_prima_address_code":"0"},"shipping":{"order-shipping_address_firstname":"test","order-shipping_address_lastname":"test","order-shipping_address_street0":"6 test","order-shipping_address_street1":"test","order-shipping_address_city":"","order-shipping_address_country_id":"GB","order-shipping_address_region":"","order-shipping_address_postcode":"16","order-shipping_address_telephone":"","order-shipping_address_vat_id":"","order-shipping_address_prima_address_code":"0"}}
May be the type of response is String. In that case convert the response into json using
response = JSON.parse(response);
before using response for iteration.
I don't say, it will help, but there are several things that should be checked for issue root:
Check whether the elements exist and they are really unique (since ids are used). console.log(i, $j('#' + i).size()) may do the trick. I believe that there may be no elements to set values.
Use val argument directly instead of referencing it through response['billing'][i]. Though I don't see how the response var may be overridden or hidden, but let's use the value directly since it's passed into callback.
"This" is what I retrieve from a server:
after an ajax call in jQuery:
$.ajax({
type: "POST",
url: URL + "/webservices/WS.asmx/MyFunction",
data: JSON.stringify({ "ID": ID }),
contentType: 'application/json; charset=utf-8',
success: function (json) {
},
error: function (jqxhr, text, error) {
}
});
and I want to iterate the items inside data (which is an array). Tried with:
for (i in json.data) {
var feed = json.data[i];
console.log(feed.message);
}
but it prints nothing. Where am I wrong?
If what you've shown is really what you're getting in your success method, you have an object with a property, d, which contains a JSON string. You can parse it like this:
success: function(response) {
var data = $.parseJSON(response.d).data;
// use the data, which is an array
}
From your comment below:
But why I need to use $.parseJSON? Can't just manage it with the request? dataType for example, but still not works.
You don't need dataType, it would appear the server is returning a correct MIME type and so jQuery is already handling the first level of parsing (deserialization) correctly.
Whatever is sending you the data appears to be sending it double-encoded: First it encodes the array, then creates an object and assigns the array to it as a data property, serializes that object to JSON, then puts that string on a d property of another object, and serializes that. So although jQuery is automatically handling the first parsing (deserializing) step for you, it doesn't know about the need for the second one. I suspect you can fix this at the server level; you might want to post a separate question asking how to do that.
From your further comment:
It retuns from a .NET webservice method. I download the JSON from Facebook, after a call. And I store it inside a json variable. Then I just return it as string. I think webservice serialize that already serialized json, right?
Ah, so that's what's going wrong. You have three options:
Keep doing what you're doing and do the explicit $.parseJSON call above.
Do whatever you need to do in your web method to tell it that you're going to send back raw JSON and it shouldn't encode it; in that case, jQuery will have already parsed it for you by the time you receive it in success and you can drop the parseJSON call.
Parse the string you get from Facebook, then put the resulting array in the structure that your web method returns. Then (again) jQuery will parse it for you and you can use response.d.data directly without further parsing.
As #T.J.Crowder has pointed out your problem is related to the way you serialize your data on your backend, which is not a good practice to send the json as a string, in a real json object.
you should do it like:
success: function (json) {
var jsonObject = JSON.parse(json.d);
//then iterate through it
for(var i=0;i<jsonObject.data.length;i++){
var feed = jsonObject.data[i];
console.log(feed);
}
},
The point is using for(var key in jsonObject.data), is not safe in JavaScript, because additional prototype properties would show up in your keys.
Try using
for (var i in json.d.data) {
var feed = json.d.data[i];
console.log(i+" "+feed);
}
where
i = Key &
feed = value
I assume json is an object not string and already converted to json object. Also used json.d.data not json.data
use var in for loop and print feed not feed.message:
for (var i in json.d.data) {
var feed = json.d.data[i];
console.log(feed);
}
because I can not see {feed:{message:''}} there
This is a newbie JavaScript question, but something I'm not quite sure how to google for help because I'm not sure how to describe the problem in an easy way.
I have a large, somewhat complex JSON that I need to manipulate so that I could reshape the JSON in a way that I get a list of only countries, cities, and sales.
The JSON itself isn't the issue for me, it's what I would like to do with it once I've received it. Basically, I'd like to create 3 separate objects/arrays from a large received JSON and have those 3 separate objects/arrays accessible for usage OUTSIDE of the $.ajax call. Yes, I think I could do all of this inside of the $.ajax success callback, but I'd rather have all the JSON processing done elsewhere. My pseudo JavaScript looks something like this:
var model = {
countries: [],
cities: [],
sales: [],
set: function(data) {
//manipulate data here so that model.countries, model.cities, model.sales are populated
}
};
$.ajax({
url: 'example.com/sample.json',
success: function(data) {
model.set(data); //is this the right way to do this?
}
});
$('#countries').html(model.countries);
$('#cities').html(model.cities);
$('#sales').html(model.sales);
But because JavaScript executes asynchronously, the last 3 lines are always blank because the JSON hasn't been received yet.
So I guess my question is, how do I bind the results of my received JSON to a variable outside of the $.ajax scope so that I could use it wherever on the page?
The simple solution is this:
$.ajax({
url: 'example.com/sample.json',
success: function(data) {
model.set(data);
$('#countries').html(model.countries);
$('#cities').html(model.cities);
$('#sales').html(model.sales);
}
});
If you want something more frameworky, then you could look at a something like Backbone.js.
Populate your HTML (i.e. update your view) in the AJAX success callback. i.e.
function updateView() {
$('#countries').html(model.countries);
$('#cities').html(model.cities);
$('#sales').html(model.sales);
}
$.ajax({
url: 'example.com/sample.json',
success: function(data) {
model.set(data); //is this the right way to do this?
updateView();
}
});
Just put those 3 line in the success callback (you can also separate it into a function) and skip the model population.
There are frameworks that allow you to bind DOM elements to JS objects and their data, bu in this case it might be an overkill.