I'm stumped. I am not sure why my JSON object is not being parsed by my callback function.
I am getting the following error in the console log:
TypeError: data is undefined
for (var i = 0, len = data.features.length; i < len; i++) {
Your help is greatly appreciated!
The ajax code:
$.ajax({
type : 'POST',
url : 'timezone.php',
dataType : 'json',
data : { "func" : "getFirstAndNext", epochTime : browserUTC },
success : function( data ) {
console.log( data.first );
console.log( data.next );
sector_callback( data.first );
// do something with data.myObject.memberVariable
},
error : function ( XMLHttpRequest, textStatus, errorThrown ) {
// didn't work!
}
});
The PHP script:
<?php
//header('Content-Type: application/json; charset=utf-8');
function getFileStamp($type) {
$timeInterval = 15; // minutes
$now = round($_POST['epochTime'] / 1000);
$now = round(1352324181061 /1000 ); // 3:36:21
//$now = round(1352238011.067);
$offsetInSeconds = $timeInterval * 60;
$offsetInMillis = $timeInterval * 60 * 1000;
$currentFileTime = $now - $now % ($timeInterval * 60);
//$currentFileTime = ($now - ($now % $offsetInMillis))/1000.0; // this returns epoch time in $timeInterval minutes.
$nextFileTime = $currentFileTime + $offsetInSeconds; // next epoch time for file;
return ($type == 0) ? $currentFileTime : $nextFileTime;
}
$currentFileTime = getFileStamp(0) . '.json';
$nextFileTime = getFileStamp(1) . '.json';
$res = array();
$res['file1'] = file_get_contents($currentFileTime);
$res['file2'] = file_get_contents($nextFileTime);
echo json_encode(array("first"=>$res['file1'],"next"=>$res['file1'])); //takes contents and converts it to json object
?>
The sector callback function:
var allPolygons = [];
function sector_callback() {
//console.log(data);
var bounds = new google.maps.LatLngBounds();
for (var i = 0, len = data.features.length; i < len; i++) {
var coords = data.features[i].geometry.coordinates[0];
siteNames = data.features[i].properties.Name; // added for site names
var path = [];
for ( var j = 0, len2 = coords.length; j < len2; j++ ){ // pull out each set of coords and create a map object
var pt = new google.maps.LatLng(coords[j][1], coords[j][0])
bounds.extend(pt);
path.push(pt);
}
var polygons = new google.maps.Polygon({
path: path,
strokeColor: "#000000",
strokeOpacity: 0.8,
strokeWeight: 1,
fillColor: "#000000",
fillOpacity: 0.35,
map: map
});
createClickablePoly(polygons, siteNames);
google.maps.event.addListener(polygons, 'mouseover', function() {
var currentPolygon = this;
currentPolygon.setOptions({
fillOpacity: 0.45,
fillColor: "#FF0000"
})
});
google.maps.event.addListener(polygons, 'mouseout', function() {
var currentPolygon = this;
currentPolygon.setOptions({
fillOpacity: 0.35,
fillColor: "#000000"
})
});
allPolygons.push(polygons);
}
}
Going off only what I can see here, I'm not seeing how your sector_callback() can access the data anyway. When jQuery passes in the data, if all else is well, your console should log those properties just fine. But when you pass some of that data to your sector_callback(), it's getting lost. The reason is that your sector_callback() either needs to read the arguments[] array to get it, or you need to change the function signature to sector_callback(data).
In your jQuery block, pass data and not data.features:
sector_callback( data );
And change your own callback signature:
function sector_callback(data) {
console.log(data); // will log the whole chunk of the server data returned
...
}
This is because data is in a closure when it comes back to your jQuery callback. Even if you've declared it somewhere outside of that closure, it's going to retain local scope and cannot be accessed by your other function unless you pass it explicitly.
Hope I've understood the crux of the problem here and this was helpful ...
Related
I have a system trying to display a graph of a count over time using flot js. The issue I am having is that the graph isnt actually rendering any lines. I have cast the time to UTC and multiplied by 1000 as suggested in other posts but to no avail. Does anyone have any idea what I am doing wrong?
PHP:
public function liveGraphAjax()
{
$query = "SELECT
time as time,
COUNT( id ) as count
FROM table
WHERE HOUR( TIME ) = HOUR( CURRENT_TIME ) -1
GROUP BY DATE_FORMAT(`time`, '%H:%i')";
$result = DB::select($query);
if(isset($result))
{
$temp = array();
foreach ($resultas $row )
{
$temp [] = array(
'time' =>strtotime($row->time) * 1000,
'count' =>(int) $row->count,
);
}
}
return Response::json($temp);
}
JS:
var options = {
colors : [$UpdatingChartColors],
xaxis: {
mode: "time",
timeformat:"%hh:%mm"
},
series: {
lines: { show: true },
points: { show: true }
},
};
$("button.dataUpdate").click(function ()
{
data = [];
$.plot("#updating-chart", data, options);
function fetchData()
{
function onDataReceived(series)
{
var res = [];
data = [series];
for (var i = 0; i < data[0].length; ++i)
{
res.push([data[0][i].time,data[0][i].count]);
}
console.log(res);
$.plot("#updating-chart", res, options);
}
$.ajax({
url: "liveGraphAjax",
type: "GET",
dataType: "json",
success: onDataReceived
});
}
});
The fetchData() function is never called so you never get data.
In your onDataReceived() function the res variable contains only one data series. You have to change your call to $.plot("#updating-chart", [res], options);
Admittedly, there are similar questions lying around on Stack Overflow, but it seems none quite meet my requirements.
Here is what I'm looking to do:
Upload an entire form of data, one piece of which is a single file
Work with Codeigniter's file upload library
Up until here, all is well. The data gets in my database as I need it. But I'd also like to submit my form via an AJAX post:
Using the native HTML5 File API, not flash or an iframe solution
Preferably interfacing with the low-level .ajax() jQuery method
I think I could imagine how to do this by auto-uploading the file when the field's value changes using pure javascript, but I'd rather do it all in one fell swoop on for submit in jQuery. I'm thinking it's not possible to do via query strings as I need to pass the entire file object, but I'm a little lost on what to do at this point.
Can this be achieved?
It's not too hard. Firstly, take a look at FileReader Interface.
So, when the form is submitted, catch the submission process and
var file = document.getElementById('fileBox').files[0]; //Files[0] = 1st file
var reader = new FileReader();
reader.readAsText(file, 'UTF-8');
reader.onload = shipOff;
//reader.onloadstart = ...
//reader.onprogress = ... <-- Allows you to update a progress bar.
//reader.onabort = ...
//reader.onerror = ...
//reader.onloadend = ...
function shipOff(event) {
var result = event.target.result;
var fileName = document.getElementById('fileBox').files[0].name; //Should be 'picture.jpg'
$.post('/myscript.php', { data: result, name: fileName }, continueSubmission);
}
Then, on the server side (i.e. myscript.php):
$data = $_POST['data'];
$fileName = $_POST['name'];
$serverFile = time().$fileName;
$fp = fopen('/uploads/'.$serverFile,'w'); //Prepends timestamp to prevent overwriting
fwrite($fp, $data);
fclose($fp);
$returnData = array( "serverFile" => $serverFile );
echo json_encode($returnData);
Or something like it. I may be mistaken (and if I am, please, correct me), but this should store the file as something like 1287916771myPicture.jpg in /uploads/ on your server, and respond with a JSON variable (to a continueSubmission() function) containing the fileName on the server.
Check out fwrite() and jQuery.post().
On the above page it details how to use readAsBinaryString(), readAsDataUrl(), and readAsArrayBuffer() for your other needs (e.g. images, videos, etc).
With jQuery (and without FormData API) you can use something like this:
function readFile(file){
var loader = new FileReader();
var def = $.Deferred(), promise = def.promise();
//--- provide classic deferred interface
loader.onload = function (e) { def.resolve(e.target.result); };
loader.onprogress = loader.onloadstart = function (e) { def.notify(e); };
loader.onerror = loader.onabort = function (e) { def.reject(e); };
promise.abort = function () { return loader.abort.apply(loader, arguments); };
loader.readAsBinaryString(file);
return promise;
}
function upload(url, data){
var def = $.Deferred(), promise = def.promise();
var mul = buildMultipart(data);
var req = $.ajax({
url: url,
data: mul.data,
processData: false,
type: "post",
async: true,
contentType: "multipart/form-data; boundary="+mul.bound,
xhr: function() {
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position; /*event.position is deprecated*/
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
def.notify(percent);
}
}, false);
}
return xhr;
}
});
req.done(function(){ def.resolve.apply(def, arguments); })
.fail(function(){ def.reject.apply(def, arguments); });
promise.abort = function(){ return req.abort.apply(req, arguments); }
return promise;
}
var buildMultipart = function(data){
var key, crunks = [], bound = false;
while (!bound) {
bound = $.md5 ? $.md5(new Date().valueOf()) : (new Date().valueOf());
for (key in data) if (~data[key].indexOf(bound)) { bound = false; continue; }
}
for (var key = 0, l = data.length; key < l; key++){
if (typeof(data[key].value) !== "string") {
crunks.push("--"+bound+"\r\n"+
"Content-Disposition: form-data; name=\""+data[key].name+"\"; filename=\""+data[key].value[1]+"\"\r\n"+
"Content-Type: application/octet-stream\r\n"+
"Content-Transfer-Encoding: binary\r\n\r\n"+
data[key].value[0]);
}else{
crunks.push("--"+bound+"\r\n"+
"Content-Disposition: form-data; name=\""+data[key].name+"\"\r\n\r\n"+
data[key].value);
}
}
return {
bound: bound,
data: crunks.join("\r\n")+"\r\n--"+bound+"--"
};
};
//----------
//---------- On submit form:
var form = $("form");
var $file = form.find("#file");
readFile($file[0].files[0]).done(function(fileData){
var formData = form.find(":input:not('#file')").serializeArray();
formData.file = [fileData, $file[0].files[0].name];
upload(form.attr("action"), formData).done(function(){ alert("successfully uploaded!"); });
});
With FormData API you just have to add all fields of your form to FormData object and send it via $.ajax({ url: url, data: formData, processData: false, contentType: false, type:"POST"})
I'm writing a "betting" script so-to-speak, and making an automated system.
The bettor will be able to choose to increase the amount or decrease the amount on win or loss.
The PHP script I wrote returns echo json_encode(array('result' => 'win')); or 'loss' for a loss.
Why won't the below code update that value of the amount dependent upon the result?
$(document).ready(function(){
function updateValuesAuto() {
// Grab all the value just incase they're needed.
var multiplier_auto = $('#multiplier_auto').val();
var percentage_auto = $('#percentage_auto').val();
var bet_amount_auto = $('#bet_amount_auto').val();
var profit_amount_auto = $('#profit_amount_auto').val();
multiplier_auto = (100-1)/percentage_auto;
profit_amount_auto = (bet_amount_auto*multiplier_auto)-bet_amount_auto;
$('#multiplier_auto').val(multiplier_auto);
$('#percentage_auto').val(percentage_auto);
$('#bet_amount_auto').val(bet_amount_auto);
$('#profit_amount_auto').val(profit_amount_auto);
}
$('#multiplier_auto').keyup(updateValuesAuto);
$('#percentage_auto').keyup(updateValuesAuto);
$('#bet_amount_auto').keyup(updateValuesAuto);
$('#profit_amount_auto').keyup(updateValuesAuto);
var runI = null;
var $run = $('#start');
var $times = $('#amount_bets');
var $stop = $('#stop');
$run.on('click', function() {
event.preventDefault();
$(this).attr('disabled', true);
$stop.attr('disabled', false);
var ran = 0;
var val = parseInt($times.val(), 10);
if(isNaN(val) || val === 0 ) return false;
runI = setInterval(function() {
if( ran < val ) {
$.ajax({
url: './requests/bet.php',
type: 'POST',
data: { amount: $('#bet_amount_auto').val(), chance: $('#percentage_auto').val(), multiplier: $('#multiplier_auto').val(), profit: $('#profit_amount_auto').val() },
}).done(function(result) {
var result = JSON.parse(result);
if( result === 'win' ) {
$('#bet_amount_auto').val() = $('#bet_amount_auto').val() * $('#wini').val();
}
else if( result === 'loss' ) {
$('#bet_amount_auto').val() = $('#bet_amount_auto').val() * $('#lossi').val();
}
ran++;
});
}
else {
clearInterval(runI);
$run.attr('disabled', false);
}
}, 500);
});
$stop.on('click', function() {
event.preventDefault();
clearInterval(runI);
$run.attr('disabled', false);
});
});
Thanks.
You may want to trim down the code to the specifics of the problem if the answer does not help, but would behoove you to actually look at the data that gets sent back. It will be:
{"result":"win"}
So to access the result in the .done function, you'd need to use result.result.
Additionally, if you are sending JSON back, jQuery may be parsing it automatically and JSON.parse may result in an error. To get jQuery to do this, send the JSON content-type header via PHP:
header("Content-type: application/json");
I believe the problem is === because three equals is a strict operator which means value and type must be equal.
In your case it seems you're trying to make sure that result is type of JSON and equals to STRING
Try double-equals == maybe?
EDIT:
Oh got that now...
Actually, you can't assign value to the result of a function. So,
Change this:
$('#bet_amount_auto').val() = $('#bet_amount_auto').val() * $('#wini').val();
to
$('#bet_amount_auto').val($('#bet_amount_auto').val() * $('#wini').val());
Two things:
1.You cannot set value to functions (You cannot put functions in the left side of an assignment)
2.result is JSON and you need to use result.result
$.ajax({
url: './requests/bet.php',
type: 'POST',
data: { amount: $('#bet_amount_auto').val(), chance: $('#percentage_auto').val(), multiplier: $('#multiplier_auto').val(), profit: $('#profit_amount_auto').val() },
}).done(function(result) {
if( result.result === 'win' ) {
$('#bet_amount_auto').val($('#bet_amount_auto').val() * $('#wini').val()) ;
}
else if( result.result === 'loss' ) {
$('#bet_amount_auto').val($('#bet_amount_auto').val() * $('#lossi').val()) ;
}
ran++;
});
Thanks for the help in this forum and i almost complete my assignment in searching the shortest route between a starting point and many markers. However, my distance measurment is simply adopting Haversine formula but it is not showing the true routing distance between two points. I am trying to combining the previous developed functions that have already been worked in Google Map to obtain the shortest distance between two point using the DirectionServices. From the following homepage, i found the method to calculate the distance of each route.
http://ratan.com.np/calculate-distance-location-longitude-latitude-google-maps-v3-route/
and I have checked my codes repeatedly but i still don't know why the code failed... it returned a syntax error 'unexpected token <'....
Can anyone help me to take a look on the code... to see any conceptual mistake in my revised program.... Many Many Thanks...
Click a button to call 'Submit2() function
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var origin = null;
var destination = null;
var markersArray = [];
var start_lat = null;
var start_long = null;
var end_lat = null;
var end_long = null;
var station_num = null;
var trig_name = null;
var total_dist;
var closest_dist;
var closest_marker;
var Submit2=function() {
var URL2="Search_nearest_trig_advanced.php"; //Call another PHP to load all markers in JSON format
$.ajax({
url: URL2,
type: "POST",
dataType: "json",
success: function(data){
$.each(data, function(i, item) {
start_lat = item.start_lat; //Return the Lat, Lng of the Starting point from Textbox
start_long = item.start_long;
station_num = item.station_num;
trig_name = item.trig_name;
end_lat = item.end_lat;
end_long = item.end_long;
origin = new google.maps.LatLng(start_lat, start_long); //Origin and Destination parameters are used for Google Direction Services
destination = new google.maps.LatLng(end_lat, end_long);
marker = new google.maps.Marker({
map: map,
position: destination,
icon: trigicon,
title: trig_name
})
markersArray.push(marker);
calcRoute2(); //find the total distance 'total_dist' for each route
if (total_dist > closest_dist) { //Replace the closest_marker by the one with shorter distance
closest_dist = total;
closest_marker.setMap(null);
closest_marker = marker;
}
});
},
error:function(xhr, ajaxOptions, thrownError){
alert(xhr.status);
alert(thrownError);
}
});
destination = closest_marker.getPosition();
calcRoute(); //the original method to show the route
};
Call the calcRoute() function to calculate the route distance
function calcRoute2() {
document.getElementById("directions_panel").innerHTML = "";
directionsDisplay = new google.maps.DirectionsRenderer({
'map': map,
'preserveViewport': false, //Google Map will change the zoom extent to match with the Direction route if set false
'draggable': true
});
var request = {
origin: origin,
destination: destination,
waypoints: waypoints,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
optimizeWaypoints: document.getElementById('optimize').checked,
avoidHighways: document.getElementById('highways').checked,
avoidTolls: document.getElementById('tolls').checked
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
computeTotalDistance(response);
}
});
directionsVisible = false;
}
function computeTotalDistance(result) {
var total_dist = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total_dist += myroute.legs[i].distance.value;
}
total_dist = total_dist / 1000 // the distance output is converted to KiloMeter
}
The 'search_nearest_trig_advanced.php'
<?php
require_once "dbconnect.php";
require_once "hk1980.php";
$coor_x = $_POST['hk80_x'];
$coor_y = $_POST['hk80_y'];
/* Connect to the MySQL database. */
if (!($connection = # mysql_connect($remotehost, $username, $password)))
die("Connection failed");
if (!(mysql_select_db($database, $connection)))
die("Couldn't select testing database");
// Run the query on the connection
$sql_query = "Select station_num, trig_name, X(trig_xy_pos) as X_Coor, Y(trig_xy_pos) as Y_Coor From trig_station";
if (!($sql_result = # mysql_query($sql_query, $connection)))
die("Couldn't run query");
while ($row = # mysql_fetch_array($sql_result, MYSQL_ASSOC))
{
$start_east = floatval($coor_x);
$start_north = floatval($coor_y);
$hk1980_start = array($start_east, $start_north);
$end_east = floatval($row['X_Coor']);
$end_north = floatval($row['Y_Coor']);
$hk1980_end = array($end_east,$end_north);
$wgs84_start = hk1980_to_wgs84($hk1980_start[1],$hk1980_start[0],2);
$wgs84_end = hk1980_to_wgs84($hk1980_end[1],$hk1980_end[0],2);
$row_set[] = array("start_lat" => $wgs84_start[0], "start_long" => $wgs84_start[1], "station_num" => $row['station_num'],"trig_name" => $row['trig_name'],"end_lat" => $wgs84_end[0],"end_long" => $wgs84_end[1]);
}
echo json_encode($row_set);
?>
The DistanceMatrix does not return route turn-by-turn directions. You have to use the DirectionsService for that. So, what you want to do is pass your origin and destinations to the Matrix first and find the shortest route. After you found the shortest route pass that route to the directions service to get the turn-by-turn information.
If you need to cycle through many routes you may have to use a premium service. Google limits the free access to its services to prevent abuse.
Here is a working example of the concept
Relevant code:
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [origin], //array of origins
destinations: destinations, //array of destinations
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
//we only have one origin so there should only be one row
var routes = response.rows[0];
//need to find the shortest
var lowest = Number.POSITIVE_INFINITY;
var tmp;
var shortestRouteIdx;
var resultText = "Possible Routes: <br/>";
for (var i = routes.elements.length - 1; i >= 0; i--) {
tmp = routes.elements[i].duration.value;
resultText += "Route " + destinations[i] + ": " + tmp + "<br/>";
if (tmp < lowest) {
lowest = tmp;
shortestRouteIdx = i;
}
}
//log the routes and duration.
$('#results').html(resultText);
//get the shortest route
var shortestRoute = destinations[shortestRouteIdx];
//now we need to map the route.
calculateRoute(origin, shortestRoute)
}
}
//Calculate the route of the shortest distance we found.
function calculateRoute(start, end) {
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
If you are trying to get the driving distance to multiple locations and don't need the route, use the DistanceMatrix
I try to make a spline highchart and implement solution from How to load data from JSON to Highchart?, that's an answer from Mina Gabriel. The codes look like this.
In test.php
}
// Set the JSON header
header("Content-type: text/json");
// The x value is the current JavaScript time, which is the Unix time multiplied by 1000.
$x = time() * 1000;
$y = rand(0,100) ;
// Create a PHP array and echo it as JSON
$ret = array($x, $y);
echo json_encode($ret);
?>
And in the highchart script:
<script>
/**
* Request data from the server, add it to the graph and set a timeout to request again
*/
var chart; // global
function requestData() {
$.ajax({
url: 'http://localhost:8080/test.php',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 20; // shift if the series is longer than 20
// add the point
chart.series[0].addPoint(point, true, shift);
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: requestData
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 100,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value',
margin: 80
}
},
series: [{
name: 'Random data',
data: []
}]
});
});
</script>
< /head>
<body>
And those just work well. But when I try to change the code in the test.php to set the y-value as a number from database like this:
<?php
header("Content-type: text/json");
$db = mysql_connect("localhost","myusername","mypassword");
mysql_select_db("mydatabase");
$day=date('Y-m-d'); //UTC standar time
$result = mysql_query("SELECT COUNT(*) FROM table WHERE time='{$day}';");
$count = mysql_fetch_array($result);
// The x value is the current JavaScript time, which is the Unix time multiplied by 1000.
$x = time() * 1000;
$y = $count[0];
// Create a PHP array and echo it as JSON
$ret = array($x, $y);
echo json_encode($ret);
?>
the line chart doesnt work. I've checked the sql code and it just works right. Did I miss something?
From the given information and this post, my best bet to the issue is that the $count[0] is a string, highcharts needs it to be strictly numeric. Could you try the following for me
$y = intval($count[0]); // OR floatval($count[0]);