Okay so after searching Stack Overflow for answers I found two threads and tried them both but they did not work for me.
Assign data from jQuery getJSON to array
How to get JSON array from file with getJSON?
My issues is I want to work with some data from a database for a mapping utility, however some elements of the JSON dissappear after you call the Jquery method $.getJSON(). I can create them to a 'ul' element just fine. I CANNOT get them to push to an array of array's with any method I have tried yet. I am asking here as I am curious what I am doing wrong. I have thought I may have to traverse the DOM to get the elements once populated maybe but that seems silly to me and I was wondering if there was an easier way potentially. I am a novice at javascript and Jquery but understand programming concepts.
The concepts I am using are this:
I have a SQL Server 2008 database with values:
PlaceID PlaceName
1 Place 1
2 Place 2
3 Place 3
4 Place 4
I can create a PHP script with the 'sqlsrv' driver to get the values and output a
echo json_encode($data);
I can confirm I can return the data from this PHP script in IIS locally. (with all the special jerry rigging you have to do to IIS to make it like PHP)
I can call the php script and display it's data with JQuery library 2.0.3.js using the
$.getJSON('SqlTalk.php')
I can populate elements in the HTML with this, but I cannot get an array of array's for reuse with other objects, which is what I really really want. Ultimately I want to make an entire javascript that just gets an array of arrays from the PHP script and then reference that javascript either embedded or as a reference to use for mapping. However it appears $.getJSON is asychrnonous from my reading but even the methods I am seeing are not working for me to attempt to 'push' to an existing array. It may be that I am misunderstanding syntax when mixing Jquery and traditional javascript as well though.
Complete HTML code where the bottleneck is. Basically PHP will be returning data as shown in step 1 except as a JSON object. This is a simple example to get me beyond proof of concept first. I can push explicitly to the array, and I can generate the child items of the ul element just fine. I cannot push the items from 'getJSON' at all no matter what I attempt at reformating the getJSON method from what I have read.
<html>
<head>
<script type='text/javascript' src='JQuery 2.0.3.js'></script>
</head>
<body>
<ul></ul>
<script>
test = [
{
PlaceID: "1",
PlaceName: "Somewhere"
}
]
test.push({PlaceID: "2", PlaceName: "SomewhereElse"});
function getArray() {
return $.getJSON('SqlTalk.php')
}
getArray().done(function(json){
$.each(json, function(key, val){
//test[key] = { PlaceID: val.PlaceID}; // doesn't work
test.push({PlaceID: val.PlaceID, PlaceName: val.PlaceName}); // also does not work, can't push.
$('ul').append('<li id="' + key + '">' + val.PlaceName + '</li>');
});
});
alert(test.length);
// So I get my output to the 'ul' element fine, but my test array never gets the values.
//I have tried what others have stated and it does not work.
</script>
</body>
</html>
The global will not be updated until after the request is complete.
var getArrayPromise = getArray().done(function(json){
$.each(json, function(key, val){
//test[key] = { PlaceID: val.PlaceID}; // doesn't work
test.push({PlaceID: val.PlaceID, PlaceName: val.PlaceName}); // also does not work, can't push.
$('ul').append('<li id="' + key + '">' + val.PlaceName + '</li>');
});
});
getArrayPromise.done(function(){
alert(test.length);
});
there is no workaround, that's just how asynchronous requests work. The clock keeps ticking and the code keeps executing while the request is being received.
You might want to use the complete callback on the AJAX response
$.ajax({
url: 'SqlTalk.php',
dataType: 'json',
success: function(data){
for (var i = 0; i < data.length; i++) {
test.push({PlaceID: data[i].PlaceID, PlaceName: data[i].PlaceName});
$('ul').append('<li id="' + i + '">' + data[i].PlaceName + '</li>');
}
},
complete: function(){
console.log(test);
}
});
I did a quick jsfiddle ( http://jsfiddle.net/Ar7kX/ ) to show the complete callback in action (using another kind of data and way, since I don't have obviously access to your real data :) ), a more proper one with arrays of arrays to follow in minutes (if I know how I can gather foursquare data from a jsfiddle)
EDIT
Here you can see an array of array in action directly pulled from foursquare http://jsfiddle.net/f38F3/1/ (30 items), hope this reflects the same situation you have pulling data from your php script
Related
I am looking to display the total number of files in a database. To clarify, say I had a website where people could upload pictures of their cars, and I wanted to display a live number of how many pictures there are, what would be the best way to do this? Javascript, php? A mix? I envision a div with a number saying "Total Pictures: x" and where x would be whatever the live total is. I plan on using MySQL to store all the data on the website. Is this even recommended to have something communicate with the server this much? Is there a name for displaying a live number? Thanks!
If you are thinking to use the AngularJS way, you could create a Poller service which polls every second (assuming your /counter.php returns json):
app.factory('Poller', function($http, $timeout) {
var data = { response: {}};
var poller = function() {
$http.get('/counter.php').then(function(r) {
data.response = r.data;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});
Then your controller:
app.controller('CounterCtrl', function(Poller, $scope){
$scope.counter = Poller.data;
});
And finally in your view:
{{counter.response}}
You can read more about $http
Set up a PHP script that queries the database and returns the total file upload count. After that, you can use JavaScript on the page to periodically call the server in a specified interval of time and fetch the count data from your PHP script. Using jQuery and GET, you can do something like this:
jQuery(function($){
setInterval(function(){
$.get( '/counter.php', function(fileUploadCount){
$('#counter').html( fileUploadCount );
});
},20000); // 20 seconds
});
In your HTML:
<p><span id='counter'>xx</span> files have been uploaded so far!</p>
Hope this helps!
How live do you want it to be? Just whenever someone updates the site it's going to have the new value or do you actually want it to update in near real-time?
If it's the latter you have to use Javascript against some kind of API that returns the amount of files in the database. I can't help you with that bit since you are using PHP, but it shouldn't be too hard. Just return some JSON looking something like
{ fileCount: 45020 }
Client-side you have a few options. You have the different javascript frameworks like AngularJS and EmberJS (and many more), as well as just 'plain old' javascript and frameworks like jQuery
The keyword is really AJAX, even if that is just a sort of buzzword for using javascript to make websites dynamic.
I am a fan of using AngularJS because it's easy, but I'll try to give you some pointers for using jQuery first. Note that I have not used jQuery in years now.
The jQuery way
jQuery has a function called jQuery.getJSON(), and according to the documentation you can use that function something like this:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON( "http://example.com/api/fileCount.json")
.done(function(data) { console.log(data) })
.fail(function() { console.log( "error" ); })
.always(function() { console.log( "complete" ); });
So this means we can call an endpoint and fetch some data using jQuery.
Here is a link to a tutorial about the basics of jQuery by the way.
jQuery makes us able to do things like this:
<div id="divTest1"></div>
<script type="text/javascript">
$("#divTest1").text("Hello, world!");
</script>
When that is executed the div with id "divTest1" will contain the text 'Hello, world!'.
That sounds like something we could use here!
Javascript also has this really nice function called setTimeout(), which allows us to make it call a function later.
This describes how to use jQuery with setTimeout()
As you can see it also shows us jQuery.documentReady(), which is an event that fires when the website is finished loading, so it is a good place to put code we want executed.
The example below shows how to use jQuery to hide a div with id=div after 3 seconds.
jQuery(document).ready(function () {
setTimeout( "jQuery('#div').hide();",3000 ); //hide a div after 3 seconds
});
Combining these things you should be able to make a repeating call that fetches data from your server and then updates a div or another element with the data you have fetched.
Just create a function which uses jQuery.getJSON() to fetch data, and then at the bottom of that add a setTimeout call to run itself in X seconds (however often you want it to update).
In jQuery.documentReady() you call that function the first time the document loads.
And in the .done() bit of the getJSON() call you add the data you got from the server to your div with whatever html you want. I showed you how to use $("#divTest1").text(), but there is also a .html() which acts the same but you should use it to add html to a element.
The angular way would be to use AngularJS's $http to do the same thing, but I wouldn't recommend learning AngularJS until you have a bit of a better grasp on Javascript.
When you do though, I highly recommend it. It's a much better approach than using jQuery.
You can read about AngularJS here
I hope this helps!
I used ajax to call a php to get me some values stored in my DB.
I then echo these values in my php so that i can use the responseText property to get these retrieved values (which i want to store in a JS array) for further referral.
Here's where i get stuck. I do manage to do this when I have to retrieve just 1 row from the DB (I did this by separating the fields using a ',' and subsequently using the split() function in JS to parse the string). However when my DB returns more than 1 row then I reach a deadend as this method of mine doesn't seem to work. Kindly advice the easiest way to overcome this hurdle.
use
var jsArray = {};
$.each(response, function(i, item) {
jsArray[i] = item;
});
the above JQuery loop is equivalent to PHP loop:
foreach($response as $i => $item) {
$jsArray[$i] = $item;
}
You can convert the PHP array of multiple DB rows to json using json_encode on server side and parse JSON on the client side using javascript reading help from here. A more code oriented answer needs some code in question to work with.
It's embarrassing to have to ask, but I freely admit I'm an unseasoned Javascript developer, and I just can't figure this out. Hopefully, this will be dead simple for someone else, and I want to thank everyone here ahead of time for the help this site continually provides me.
A couple days ago, I asked this question, and am no longer getting that error. But I've run into a wall trying to actually access the data stored in the variable. My JSON looks like this:
[
{"id":"1","name":"Bob","haircolor":"Brown"},
{"id":"2","name":"Carol","haircolor":"Red"}
]
It's going into a variable like this:
var people=[];
$.getJSON("php/getpeople.php", function(data){ //getpeople.php generates the JSON
people.push(data);
});
Thanks to initializing people as an array, I no longer get any error messages. But I can't access the contents of people, either. people.length returns a 0, and people[0] and people[1] are undefined.
It's there, I know it's all there, but I'm having a devil of a time figuring out where.
people only gets values after the ajax event happens.
Call some callback function after you put the data into the people array.
Try with this: http://jsfiddle.net/hUq7k/
$.getJSON("php/getpeople.php", function(data){ //getpeople.php generates the JSON
$.each(data, function(i, people){
console.log(people.id); //<------this should output "1, 2"
});
});
make sure you are getting the response data.
The following should work, if the server is actually returning the expected JSON:
$.getJSON("php/getpeople.php", function(data){ //getpeople.php generates the JSON
var people = data;
alert("people.length: " + people.length);
if (people.length > 0) {
alert("people[0].id: " + people[0].id);
}
});
The following should not work, i.e., people will be undefined, because $.getJSON is an asynchronous method and this code is attempting to access people before the AJAX operation has completed.
var people;
$.getJSON("php/getpeople.php", function(data){ //getpeople.php generates the JSON
people = data;
});
alert("people.length: " + people.length);
if (people.length > 0) {
alert("people[0].id: " + people[0].id);
}
In my website I will have a "browse catalogue" button, which, onclick will change several elements of the page to display the catalogue element. I dont want a full page reload because several elements such as the nav bars and news feed will stay the same.
My question is how can i change several different divs with ajax onclick?
Essentially im not sure how to do place several different components in different divs across a page.
And i know there's a limit on simultaneous ajax calls, so im sure the proper way to do it wouldnt be to make a unique ajax call for each of my divs.
A little guidance would be great.
Using jQuery, you can get an json array of elements for each block that needs to be updated:
In your html page:
$.get("page.php?id=42",
function(result){
$('#title').text(result['title']);
$('#description').text(result['description']);
$('#price').text(result['price']);
}, "json");
In page.php:
$result = array('title' => 'foo', 'description' => 'bar', 'price' => 3);
echo json_encode($result);
header('Content-Type: application/json');
die();
I'm not sure if the right decision will be to send several ajax requests. Just create a request with unique attribute value, in so shape that server will know which blocks you need. On server side all required blocks concatenate in json object, and return it to client. After just parse object on blocks that should be. For example
$.ajax({
url : 'http://your.server.doment',
data : 'block[]=1&block[]=7&block[]=15',
type : 'post',
dataType : 'json',
success : function (object){
for( el in object) { $('#block_'+el).html(object[el]); }
}
});
you can use json
example
php request ajax
$div1="<table><tr><td>x</td></tr></table>";
$div2="<table><tr><td>x</td></tr></table>";
$div3="<table><tr><td>x</td></tr></table>";
$json = '{"div1":"'.$div1.'","div2":"'.$div2.'","div3":"'.$div3.'"}';
return $json;
uses jquery
$.ajax({url: 'ajax/test.php',
success: function(data) {
var obj = JSON.parse(data);
$("mydiv1").html(obj.div1);
$("mydiv2").html(obj.div2);
$("mydiv3").html(obj.div3);
}});
if you have a error in the parce function
replace spaces
example
$arr =array("\n","\t");
$div1= str_replace($arr,"",$div1);
Practically, ten or more elements updated in parallel on the page (each by a separate ajax) will not make such a big difference (unless you can test it with your website deployed into productive environment and prove I am wrong).
Nonetheless, if you wish to compact all the data exchange to one single request/response ajax call - it is very well possible but does require certain flexibility on the server side (see http://php.net/manual/en/function.json-encode.php).
I.e. one of the possible solutions is to produce json response on the server side, that generates a key-value pairs (JSON - javascript {} object) with keys being id of your elements and values being (new) html.
There are tons of ajax JS frameworks as jQuery, prototype, dojo, etc. (I will pick jQuery for this one).
Ajax request
$.ajax({
...
})
See http://api.jquery.com/jQuery.ajax/
Server response
// Assume we got
// var data = {key1:'html1',key2: 'html2'};
// Ajax handle can look like
success(data) {
$.each(data, function(key, val){
//console.log(key, val);
// Do some checks here.. But key should indicate #id of html elements
$(key).empty().append(html);
});
}
This is a basic outline but should keep you going into the right direction.
Long story short, I'm trying to store corresponding data values from a JSON returning AJAX into these global arrays. I know that the arrays are constructing correctly because I've put alerts within AJAX, but when I put it outside the AJAX, the array is still undefined.
How can I export either the entire popData JSON object to work on it and store the values in the global arrays or get the populating of the arrays in the AJAX to carry outside the call? I need these arrays to be accessible by another function to compare the population values to a narrow range of values selected by the user--if anyone wants to suggest a better way of doing this, but it has to pull the population values onLoad which is already done in the HTML. I think this is the most streamlined way to do that with the fewest AJAX calls on the server, but I'm open to suggestions! :D
var popProducers = new Array();
var popProducersCount = new Array();
function getPopulationInfo(){
$.ajax({
url:phpURL,
cache:false,
dataType:"json",
data: { },
success:function(popData){
for (i=0;i<popData.length;i++){
//producers and producersCount should be the same length at all times!
//If current producer name isn't in array already
if(popProducers.indexOf(popData[i].ProducerName) == -1){
//add new element to represent new producer quantity (producerCount.length returns number of elements in the array, thus if there are no elements = 0 thus making index 0 equal to 1 and so on)
popProducersCount[popProducersCount.length] = 1;
//Adds the producer name to the list of producers
popProducers[popProducers.length] = popData[i].ProducerName;
} else {
//Otherwise, it will increment the index of the producersCount array corresponding with the pre-existing producer name's index by 1
popProducersCount[popProducers.indexOf(popData[i].ProducerName)] += 1;
}
}
}
});
alert("Population Data Alert: " + popProducers);
.ajax() and its underlaying XMLHttpRequest() create asyncronous requestes by default. That just means, your alert() statement is encountered before your success handler.
Easy solution here, move that alert() into the success handler at the very bottom.
If you want to deal with it in a more apropriate way, you could use jQuerys Deferred objects in a way like
function getPopulationInfo(){
return $.ajax({
// lots of stuff
});
}
and then call it like
getPopulationInfo().done(function() {
alert("Population Data Alert: " + popProducers);
});
by returning the .ajax() method we implcitly return a Deferred object. Long story short, you can pass in some additional callbacks for success (.done()), error (.fail()) and complete (.always())