Steve Tinsley
asked on
Ajax to create array
I have a php page that creates a world cloud:
But I want to get the data using an ajax call.
I have written the serverside php bit which outputs
But im not sure how to get it into the javascript. This is my JS so far:
I am getting the error: Uncaught TypeError: Cannot read property 'length' of undefined
Im sure its something really obvious, but i'm not sure what it is.
<?php
$id = $_GET['id'];
try
{
$sql = "SELECT * FROM wordcloud WHERE questionID = $id";
$sql = $datadb->prepare($sql);
$sql->execute(array());
}
catch(PDOException $e)
{
echo $e->getMessage();
die;
}
?>
<script type="text/javascript">
var word_list = [
<?php
while($r = $sql->fetch(PDO::FETCH_ASSOC)){
echo "{text: \"" . $r['keyword'] . "\", weight:". $r['weight'] ."},";
}
?>
];
$(document).ready(function() {
$("#dynamic_wordcloud").jQCloud(word_list);
});
</script>
<div id="dynamic_wordcloud"></div>
But I want to get the data using an ajax call.
I have written the serverside php bit which outputs
[{"text":"word1","weight":"2"},{"text":"word2","weight":"1"}]
But im not sure how to get it into the javascript. This is my JS so far:
<script type="text/javascript">
function getWordcloudData(questionID) {
$.get('../library/process_output.php?action=outputWordcloudData&questionID=' + questionID, function(data) {
var resultSet = jQuery.parseJSON(data);
return resultSet;
});
}
var word_list = getWordcloudData( <?php echo $_GET['id']; ?> );
$(document).ready(function() {
$("#dynamic_wordcloud").jQCloud(word_list);
});
</script>
<div id="dynamic_wordcloud"></div>
I am getting the error: Uncaught TypeError: Cannot read property 'length' of undefined
Im sure its something really obvious, but i'm not sure what it is.
There might be something useful in this article:
https://www.experts-exchange.com/articles/22519/Understanding-JSON-in-PHP-and-JavaScript-Applications.html
A JSON string is JavaScript. You should be able to use console.log and alert() to visualize the information in the JSON string. From the current message, I'm confused by the reference to the property 'length' which does not seem apparent in your code. If you haven't tried yet, you might want to run this in Chrome with Dev Tools turned on. You may be able to find where 'length' is coming from. Good learning resources for Chrome Dev Tools here:
https://www.codeschool.com/courses/discover-devtools
You might also want to deconstruct the problem a bit - examine each piece of data looking at inputs and outputs from the subcomponents. Ask questions like "Does the PHP script always work predictably?" and "Can I see the returned JSON string in a browser request to the PHP script?"
Also, are you confident in jQCloud's usability? Are there others who are using it successfully? If this is the one you're using, the gallery links are not very inspiring.
https://github.com/lucaong/jQCloud
https://www.experts-exchange.com/articles/22519/Understanding-JSON-in-PHP-and-JavaScript-Applications.html
A JSON string is JavaScript. You should be able to use console.log and alert() to visualize the information in the JSON string. From the current message, I'm confused by the reference to the property 'length' which does not seem apparent in your code. If you haven't tried yet, you might want to run this in Chrome with Dev Tools turned on. You may be able to find where 'length' is coming from. Good learning resources for Chrome Dev Tools here:
https://www.codeschool.com/courses/discover-devtools
You might also want to deconstruct the problem a bit - examine each piece of data looking at inputs and outputs from the subcomponents. Ask questions like "Does the PHP script always work predictably?" and "Can I see the returned JSON string in a browser request to the PHP script?"
Also, are you confident in jQCloud's usability? Are there others who are using it successfully? If this is the one you're using, the gallery links are not very inspiring.
https://github.com/lucaong/jQCloud
Ahh, that image helps. The error appears to be in jQCloud itself. Maybe look for another plug-in?
ok if you did exactly what I had above, the function wasn't returning the data so go ahead and do that now:
ie.
$.getJSON('../library/proc ess_output .php?actio n=outputWo rdcloudDat a&question ID=' + questionID, function(data) {
return data;
});
You've proved it is in the right format, an array of js objects so if there's still that "length" issue then it could be as Ray says and a problem with the plugin. See how that goes above and we'll be able to do some more testing if there's still an issue.
ie.
$.getJSON('../library/proc
return data;
});
You've proved it is in the right format, an array of js objects so if there's still that "length" issue then it could be as Ray says and a problem with the plugin. See how that goes above and we'll be able to do some more testing if there's still an issue.
In fact, here is a demo of it working so I suspect it could be your data:
http://jsbin.com/gipujo/edit?html,output
http://jsbin.com/gipujo/edit?html,output
ASKER
So when I do it like your jsbin example it works
but when I do it with the ajax call in a separate function it doesn't:
is it something to do with the jQCloud function running before the ajax call has returned data??
Its working your way now but would be good to understand how to sort it my way.
$(function() {
// When DOM is ready, select the container element and call the jQCloud method, passing the array of words as the first argument.
$.getJSON('../library/process_output.php?action=outputWordcloudData&questionID=' + <?php echo $_GET['id']; ?>, function(data) {
$("#dynamic_wordcloud").jQCloud(data);
});
but when I do it with the ajax call in a separate function it doesn't:
function getWordcloudData(questionID) {
$.getJSON('../library/process_output.php?action=outputWordcloudData&questionID=' + questionID, function(data) {
return data;
});
}
$(function() {
var word_list2 = getWordcloudData( <?php echo $_GET['id']; ?> );
$("#dynamic_wordcloud").jQCloud(word_list2);
});
is it something to do with the jQCloud function running before the ajax call has returned data??
Its working your way now but would be good to understand how to sort it my way.
ASKER
Perhaps I could show a loading spinner whilst the ajax function is running?
Just a scope issue as this returns data from the callback function, NOT your function.
$.getJSON('../library/proc ess_output .php?actio n=outputWo rdcloudDat a&question ID=' + questionID, function(data) {
return data;
});
What you're after to do it your way is:
function getWordcloudData(questionI D) {
var someTempVariable = []; // an empty array
$.getJSON('../library/proc ess_output .php?actio n=outputWo rdcloudDat a&question ID=' + questionID, function(data) {
someTempVariable = data;
});
return someTempVariable;
}
However you could just set up the jQCloud in the ajax callback and show a spinner / "loading..." while that's happening (as you suggested)
$.getJSON('../library/proc
return data;
});
What you're after to do it your way is:
function getWordcloudData(questionI
var someTempVariable = []; // an empty array
$.getJSON('../library/proc
someTempVariable = data;
});
return someTempVariable;
}
However you could just set up the jQCloud in the ajax callback and show a spinner / "loading..." while that's happening (as you suggested)
ASKER
Im so sorry to keep asking...
I think its SO close
someTempVariable is returning nothing :(
I think its SO close
<script type="text/javascript">
function getWordcloudData(questionID) {
var someTempVariable = [];
$.getJSON('../library/process_output.php?action=outputWordcloudData&questionID=' + questionID, function(data) {
someTempVariable = data;
});
alert (someTempVariable); //<--- this is empty
return someTempVariable;
}
// $(function() {
// $.getJSON('../library/process_output.php?action=outputWordcloudData&questionID=' + <?php echo $_GET['id']; ?>, function(data) {
// $("#dynamic_wordcloud").jQCloud(data);
// });
// });
$(function() {
var word_list = getWordcloudData( <?php echo $_GET['id']; ?> );
$("#dynamic_wordcloud").jQCloud(word_list);
});
</script>
someTempVariable is returning nothing :(
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I'm wondering a little bit about the sequence of events. Is PHP putting the correct value into this statement? If you turn on error_reporting(E_ALL) you may be able to detect something like a missing value for $_GET['id']
PHP runs on the server and creates the "document" from HTML, CSS and JavaScript. So when we see JavaScript with a direct PHP call in it, something seems out of sequence. PHP should have already run on the server and should have already put the "id" value into the JavaScript function call. This would happen before the JavaScript was sent to the client browser for action and display. If you need a dynamic call from the client back to the server, you would need to use AJAX to send the values to the PHP script on the server.
var word_list = getWordcloudData( <?php echo $_GET['id']; ?> );
Here is why I'm wondering about that statement. PHP runs on the server and creates the "document" from HTML, CSS and JavaScript. So when we see JavaScript with a direct PHP call in it, something seems out of sequence. PHP should have already run on the server and should have already put the "id" value into the JavaScript function call. This would happen before the JavaScript was sent to the client browser for action and display. If you need a dynamic call from the client back to the server, you would need to use AJAX to send the values to the PHP script on the server.
If you were to do it by calling a function like you had, you're "blocking" execution waiting for the results to be returned from the request.
This is where view models and their associated framewords come into play such as knockoutjs and angularjs as they keep track of variables and when they change, that change is captured and you can do something like initialise a WordCloud. Overkill in this instance but worth considering for anything more complex
This is where view models and their associated framewords come into play such as knockoutjs and angularjs as they keep track of variables and when they change, that change is captured and you can do something like initialise a WordCloud. Overkill in this instance but worth considering for anything more complex
$.getJSON('../library/proc
console.dir(data); // see what is output to the console
//var resultSet = jQuery.parseJSON(data);
//return resultSet;
});
Also move the following inside your $(document).ready()
ie
$(document).ready(function
var word_list = getWordcloudData( <?php echo $_GET['id']; ?> );
$("#dynamic_wordcloud").jQ
});