Accessing data in Google Maps PHP with jQuery - javascript

I'm having trouble correctly accessing data in Google Maps API php.
Heres what example data looks in php:
{"destination_addresses":["Destination address"],"origin_addresses":["Origin address"],"rows":[{"elements":[{"distance":{"text":"3.3 km","value":3314},"duration":{"text":"6 mins","value":334},"status":"OK"}]}],"status":"OK"}
Heres my .js:
$(function(){
$("#button").click(function(){
var start = $("#start").val(); //gets start and end values from input fields, and passes them to .php which is not visible here.
var end = $("#end").val();
$.ajax({url: "googlemaps.php",
method: "GET",
data : { "start" : start, "end" : end },
success: function(result) {
print(result);
},
error: function(xhr){
alert("Error: " + xhr.status + " " + xhr.statusText);
}
});
});
});
function print(result){
var length = "";
for(var i = 0;i < result.rows.length;i++){
length += result.rows[i].text+ "<br/>";
$("#div").html(length);
}}
It should calculate the distance between two addresses, and it currently returns unidentified (which is ok), since
length += result.rows[i].text+ "<br/>";
is not correct. I have no idea how to access value "text":"3.3 km", or it's equivalent in my code. I know it is an object inside "distance", which is an array item of "elements", which is an array item of "rows".

Its structured like:
rows[0].elements[0].distance.text
You might not need the loop, but if you were to use it you would do something like.
for (var i = 0;i < result.rows.length; i++) {
for (var k = 0;k < result.rows[i].elements.length; k++) {
length += result.rows[i].elements[k].distance.text + "<br/>";
}
}
$("#div").html(length);

If your array is result, then you can access the distance by using this:
var distance = result['rows'][0]['elements'][0]['distance']['text'];

Related

Evaluating JSON dynamic name

I want to display a database value and build a bootstrap grid, building the bootstrap grid was easy however displaying the data isn't as easily built.
Normally I would call the items I wanted in the loop like this x[i].DIAG;. However I am building a dynamically variable name "s": var s = i*cNum+j so that I can call the item dynamically x[s].DIAG. When I display the value with console.log(s), I see the values I want. However, when I try output the data it breaks. Any suggestions would greatly be appreciated.
JSON example:
0: Object
DIAG:"Anaplastic"
DIAGID:13
Code:
function loadDiag(){
$.ajax({type: "GET"
, dataType: "json"
, url: "CFCs/lookUps.cfc"
, data: {method: "Diag_rlu"}
, success: function(data){
var x = data.items;
console.log(x)
var rNum = x.length / 6 //number of rows
var cNum = 6 // number of colums
var str = '';
for (var i = 0; i < rNum; i++) {
str += '<div class="row" id="'+i+'">';
for (var j = 0; j < cNum; j++) {
var s = i*cNum+j
if(s <= x.length){
str += '<div class="col-xs-2">'+x[s].DIAG+'</div>';
} else{
str += '<div class="col-xs-2"></div>';
}
}
str += '</div>';
}
$('.diagnosis').html(str);
}
});
}

Parsing JSON within JSON with jQuery

I am using the Twitch API and am attempting to pull follower images. To do this, I have to parse my most recent followers, take the name of these followers and make a request for each to obtain their user image.
$.getJSON(streamFollowers, function(json) {
for (var i = 0; i < 5; i++) {
var followerDisplayName = json.follows[i].user.display_name;
var followerName = json.follows[i].user.name;
var followerJSON = 'https://api.twitch.tv/kraken/channels/' + followerName + '';
$.getJSON(followerJSON, function(json) {
var followerImage = json.logo;
if (followerImage === "null") {
followerImage = "null.jpg";
};
});
What I am having difficulty with is attempting to pull the "followerImage" result from the "followerJSON" parse.
Heres the code in action. http://codepen.io/anon/pen/rxEPXQ
Edit: A second parse isn't required. You can pull user images from the initial parse for usernames etc. I just didn't see see it at the time. My bad.
A users logo is null if a user doesn't have a profile picture set.
http://codepen.io/anon/pen/EPBMox?editors=1011
here it is with all your followers, you can see ones with it set work properly.
var streamFollowers = "https://api.twitch.tv/kraken/channels/tsm_dyrus/follows";
$.getJSON(streamFollowers, function(json) {
for (var i = 0; i < json.follows.length; i++) {
var followerDisplayName = json.follows[i].user.display_name;
var followerName = json.follows[i].user.name;
var followerImage = json.follows[i].user.logo;
$('#followers').append('<li><img src="' + followerImage + '"></img><br />' + followerDisplayName + '</li>');
}
});

How to get the right index for a delayed trigger?

Following problem: I have an angular module with $http.get to get some google coordinates. This function triggers another function. This function again triggers another function. It will all make sense in a moment.
Angular Module:
var myApp = angular.module('wmw', []);
myApp.controller('MainCtrl', function ($scope, $http) {
//Angular Method
$scope.getTargetCords = function (data) {
$http.get(data).success(function (response) {
$(document).triggerHandler('my_func:data-received', [response]);
});
};
});
onSucess:
var onSuccess = function(position) {
currentLat = position.coords.latitude ;
currentLng = position.coords.longitude;
for(i = 0; i<locations.length;i++){
var destUrl = 'http://maps.googleapis.com/maps/api/geocode/xml?address=' + locations[i][ 'street' ] + ',' + locations[i][ 'city' ] + ',Deutschland' + '&sensor=true';
var MyAngularScope = angular.element($("#MainCtrlId")).scope();
MyAngularScope.getTargetCords('http://maps.googleapis.com/maps/api/geocode/xml?address=' + locations[i][ 'street' ] + ',' + locations[i][ 'city' ] + ',Deutschland' + '&sensor=true');
}
};
navigator.geolocation.getCurrentPosition(onSuccess, onError);
The two triggers:
$(document).on('my_func:data-received', function(event, response) {
map[s] = response;
s++;
if(s === locations.length){
$(document).triggerHandler('allData');
}
});
$(document).on('allData', function(){
var thecoords = [];
var distance = [];
$('#filter-list').empty();
for(var i = 0; i < locations.length; i++){
thecoords[0] = $(map[i]).find('lat').first().text();
thecoords[1] = $(map[i]).find('lng').first().text();
distance[i] = calculateDistance(currentLat, currentLng, thecoords[0], thecoords[1]);
locations[i]['distance'] = distance[i];
}
locations.sort(function(a,b)
{ return a.distance - b.distance;}
);
for(var i = 0;i < locations.length; i++){
distance[i] = locations[i]['distance'].toFixed(2);
distance[i] += ' KM';
locations[i]['distance'] = distance[i];
}
$('.loading').hide();
for(var i = 0; i<=5; i++){
addItemToList(locations[i]);
}
});
What's happening? With those functions I retrieve the current location, the dest location and calculate the difference in KM via a lat./long. calc function which I found on the web. .loading is just a div with "Calculating route..." and a transparent grey background. So once everything is finished, The "Distance" of every route will change to the calculated distance.
The problem with this: in my ".on('my_func:data-received')" I am using the variable "s" which is 0 at the start. In my logic I thought, that this would then put the responses one after another in my "map". But now I realised, that the "data-received" are not called one after another, but each time when data is retrieved. So when locations[0] is calling the $http.get and then after this locations[1] is calling the $http.get, it could happen, that locations[1] retrieves the data earlier. How could I have my "s" always be the right number? So that when I have locations[1] calling $http.get map[1] will be locations[1] response?
My head is exploding, as I cant find a solution to this problem, although it seems to be so basic.
Thank you in advance!
Since restructuring your application is not an option, another reasonably quick way of getting the right order is mapping the response data to the original array. The response contains the url which is built using data from the array which might give you what you need.

JSON Object (how to not load the entire object on DOM initially)

So i am reading a local json file that consist of {[Object,Object,Object.....]}
I am using the
$.getJSON('products.json', function (pdata) {
for (var i = 0; i < pdata.data.length; i++) {
AppendtoDom(pdata.data[i]);
}
The above code reads the json objects and appends to the DOM, but i want to initially load only 100 objects at a time and on scroll keep appending.
Say there are around 1200 objects. How do i go about this?
My implementaion so far
$(function(){
loadData();
});
function loadData(){
$.getJSON('products.json', function (pdata) {
var i = 0;
function addtoDom(num){
var limit = Math.min(i + num, pdata.data.length);
for(; i < limit; i++){
getInformation(pdata.data[i]);
}
}
addtoDom(100);
$('.content').jscroll({
callback: addtoDom(100)
});
});
}
function getInformation(obj){
var content = "";
for (var i = 0; i < 4; i++) {
content += '<li>';
content += "<img src='" + obj.imageUrl + "' style='width:200px;height:200px'/>";
content += '<div class="productName">' + obj.fullName + "</div>";
content += '<div class="price">Price: ' + obj.price + "</div>";
content += '</li>';
}
$("<ul class= 'view'>" + content + "</ul>").appendTo('.content');
}
Similar question i asked in How would i implement an infinite scroll in my DOM
You can put all the objects you get back from the Ajax call into a persistent variable, add the first 100 to the DOM, keep a counter of how many you've added so far and then upon scrolling to a certain point, add another 100, add another 100 and so on.
$.getJSON('products.json', function (pdata) {
var i = 0;
function addMore(num) {
var limit = Math.min(i + num, pdata.data.length);
for (; i < limit; i++) {
AppendtoDom(pdata.data[i]);
}
}
// add the first 100
addMore(100);
// then set up whatever scroll detection you want here and
// when you decide that it has scrolled enough to add some more
// you just call addMore(100) again
});
In your specific implementation of the above idea, you have an implementation mistake. You have to pass a function reference for the callback so change this:
$('.content').jscroll({
callback: addtoDom(100)
});
to this:
$('.content').jscroll({
callback: function() {addtoDom(100);}
});
Assign your JSON to a variable and dynamically render them as needed.
var json;
$.getJSON('products.json', function (pdata) {
JSON = pdata;
};
// Scheduling logic
AppendtoDom(json[i]);

Asynchronous Problems with Javascript Hacker News API

Hacker News recently released an API that I am using to display what the current top ten items are on Hacker News. I am running into some problems.
When I run the code below, the order of the items on the frontpage are inaccurate, jumping from the second one in the frontpage to the fourth, to the first, to the fifth, to the third and so on. Running the code again results in a slightly different order again.
$.getJSON('https://hacker-news.firebaseio.com/v0/topstories.json', function(json) {
var convoText = '<ol>';
for (var i = 0; i < 10; i++) {
(function(i) {
$.getJSON('https://hacker-news.firebaseio.com/v0/item/' + json[i] + '.json', function(json2) {
convoText += '<li>' + json2.title + '</li>';
if (i === 9) {
convoText += '</ol>';
addConvo(convoText);
}
});
})(i);
}
});
I understand that this is an effect of Javascript's asynchronous nature. How can I fix it?
The knack is to create and append a <li><a></a></li> structure synchronously in the loop - thereby establishing the correct order - then populate it asynchronously with json2 data when it arrives.
$.getJSON('https://hacker-news.firebaseio.com/v0/topstories.json', function(json) {
var $ol = $('<ol/>').appendTo(...);//wherever
for (var i = 0; i < Math.min(json.length, 10); i++) {
(function(i) {
var $a = $('<li><a></a></li>').appendTo($ol).find('a');
$.getJSON('https://hacker-news.firebaseio.com/v0/item/' + json[i] + '.json', function(json2) {
$a.attr('href', json2.url).text(json2.title);
});
})(i);
}
});
You will have to complete the .appendTo(...) line. I don't know from the question where the <ol>...</ol> is appended.
You can use jQueries $.when for that:
$.getJSON('https://hacker-news.firebaseio.com/v0/topstories.json', function(json) {
var requests = [];
for (var i = 0; i < 10; i++) {
requests.push($.getJSON('https://hacker-news.firebaseio.com/v0/item/' + json[i] + '.json'));
}
$.when.apply($, requests).done(function() {
var results = [].slice.call(arguments);
var list = results.map(function(arr) {
return '<li>' + arr[0].title + '</li>';
});
var convoText = '<ol>' + list.join('') + '</ol>';
console.log(convoText);
});
});
There are a few ways to fix this. The easiest is, instead of appending to convoText, use an array, and set its index when you get data. Like data[i] = json2;. Then when all your data is fetched, join your array.
A more structural fix would be to rearchitect your loop as a collection of promises, and construct your HTML when they have all resolved (what #xat was alluding to above).

Categories