This is my second question today. I am using Cordova + angular (1).
I am trying to compare two geolocation with the help of distanceInKmBetweenCoordinates function.
I am getting this error while running the app.
angular.min.js:101 ReferenceError: distanceInKmBetweenCoordinates is
not defined
at Channel.onDeviceReady
Here is the code.
document.addEventListener('deviceready', function onDeviceReady() {
angular.bootstrap(document, ['formApp']);
}, false);
var formApp = angular.module('formApp', []);
// define angular module/app
var formApp = angular.module('formApp', []);
formApp.controller('formProfile1', function($scope,$http,$location, $timeout){
function degreesToRadians(degrees) {
return degrees * Math.PI / 180;
}
function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
I am using Cordova geolocation plugin to get the current location.
navigator.geolocation.getCurrentPosition(function(position) {
$scope.userlongitude = position.coords.longitude;
$scope.userlatitude = position.coords.latitude;
Below are some ajax request to get the data from the database including geolocation to compare.
$http({
url: 'https://www.abcd.xyz/get_info.php',
method: "GET",
params: {
tn_id: $scope.tn_id
}
})
.success(function(data) {
if (data.success) {
$scope.longitude = data.longitude;
$scope.latitude = data.latitude;
}
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, $scope.latitude, $scope.longitude);
In the end, I am comparing the geolocation.
Can you advise me what am I doing wrong? If I just do the compare only in angular then it is showing me correct value but along with Cordova, it is broken.
I also made changes in the body section as follows.
<!--<body id="home" ng-app="formApp"> --> Previous one
<body id="home">
Edit 1
I changed the code like this.
degreesToRadians = function(degrees) {
return degrees * Math.PI / 180;
}
distanceInKmBetweenEarthCoordinates= function(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
$scope.distance = distanceInKmBetweenEarthCoordinates(43, 44,44,55);
alert($scope.distance);
and when I test it is giving me correct value but when I test it like this.
distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, 44,55);
then it is giving me the same error.
I used $timeout function to delay the loading but the error is same.
$timeout(function() {
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, 44,55);
alert($scope.distance);
console.log($scope.distance);
}, 5000);
As you suggested, place your code once you get the response from the ajax call,
if (data.success) {
$scope.longitude = data.longitude;
$scope.latitude = data.latitude;
$scope.distance = distanceInKmBetweenCoordinates($scope.userlatitude, $scope.userlongitude, $scope.latitude, $scope.longitude);
}
Try to assign the function to a local var in controller scope, maybe it's loosing reference:
formApp.controller('formProfile1', function($scope,$http,$location){
var degreesToRadians = function(degrees) {
return degrees * Math.PI / 180;
}
var distanceInKmBetweenEarthCoordinates = function(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) *
Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
Related
link to error message2 days back google chrome automatically updated to version 66. Since then my site which was running perfectly stopped working in google chrome. But it works perfectly in firefox and edge. So i started debugging in google chrome, then i found that the problem is with ajax calls. So initially for the main page, many ajax call will be hit. in that list of calls ,the last call executes the success part more than once. So when the susscess of response is executing for the second time it throws aw snap,page cannot be displayed error in chrome. Then i restricted the success call to once using some flag,then the main page was loading. But after submitting in left panel,the same ajax call will get hit, so now at this point i'm getting the same aw snap error. i'm using angularjs ajax. So please help me with this. when i debug i get below error message in console
error message in console
As discussed in comment this function of d3.js code causes the application to crash.So when i commented this except this chart all other things are working
var carbon = new Charts();
var chart = d3.select(this.selector);
var width = carbon.pixToVal(chart.style("width"));
var height = carbon.pixToVal(chart.style("height"));
/*var width=475;
var height=133;*/
/*var maxVal =100;*/
var maxVal =d3.max(jsonData,function(d){return d.current;})+ 15;
var length1=jsonData.length;
var newWidthParts=newWidth/10;
/*console.log(length1);
console.log(newWidth);*/
var newHeightParts=height/10;
var conatinerRectHt=newHeightParts*6.5;
/*var boxHeight=(newHeightParts*9-newHeightParts*2.5)/5;*/
var margin={
top: 15, left:15,right:15,bottom:20
}
var availableWidth = width - margin.left - margin. right;
var newWidth= availableWidth/length1;
var availableHeight = height - margin.top - margin.bottom;
var HeightForTopLabel =15;
var HeightForBottomLabel = 15;
var HeightOfAbsValue = 15;
var HeightForMidLabel = 15;
var OuterRectHeight= availableHeight - (HeightForBottomLabel) - HeightForTopLabel; /*- HeightOfAbsValue;*/
/* var BottomTextYPosition = margin.top + HeightForTopLabel + OuterRectHeight + HeightForBottomLabel ;
*/
var outerRectBottomYPosition = margin.top + HeightForTopLabel +OuterRectHeight;
//outerRectTopYPosition + OuterRectHeight
var outerRectTopYPosition = margin.top + HeightForTopLabel;
var BottomTextYPosition = height - margin.bottom;
var outerRectWidth = 50;
var innerRectWidth =8;
var outerRectDistFromLeft = newWidth/2 - outerRectWidth/2 + margin.left ;
var innerRectDistFromLeft = newWidth/2 - innerRectWidth/2 + margin.left ;
var creatSvg = chart.append("div").attr("class", "chartBox9")
.style("position", "absolute")
.style("height", "100%")
.style("width", "100%")
.append("svg").attr('id','defsGrad')
.attr("width", width)
.attr("height", height);
d3.select("#defsGrad")
.append("text").attr("x",availableWidth - 1.8*(margin.left + margin.right) )
.attr("y",height-5)
.attr("id","shareContritext")
.text("% Room Revenue")
.attr("font-size",10.5);
d3.select("#defsGrad").append("defs").append("linearGradient").attr('id','grad1')
.attr({'x1':'0%','y1':'100%','x2':'0%' ,'y2':'0%'}).append('stop')
.attr('offset',"0%").style({'stop-color':'rgb(215,214,214)','stop-opacity':'0.7'});
d3.select('#grad1').append('stop')
.attr('offset',"100%").style({'stop-color':'rgb(249,249,249)','stop-opacity':'0.9'});
svgContainer=creatSvg.selectAll('g')
.data(jsonData).enter()
.append("g")
.attr("transform",function(d,i){
var res = "translate(";
var val = i*newWidth;
return res+val+" 0)";
});
svgContainer.append("text")
.attr("y", margin.top)
.attr("font-size",fontsize)
.text(function(d) {
if( d.current == null){
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 5);
return "N/A";
}else
{
var xposition = outerRectDistFromLeft + (outerRectWidth/5+4);
var nbr = d.current;
// var decimals = (nbr!=Math.floor(nbr))?(nbr.toString()).split('.')[0].length:0;
var decimals;
if(nbr % 1 !== 0)
{
decimals = (nbr!=Math.floor(nbr))?(nbr.toString()).split('.')[0].length:0;
}else
{
decimals = nbr.toString().length;
}
d3.select(this).attr("x",xposition-(decimals-1)*4);
if(d.change==null)
{
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 5);
}
return d.current_prefix + d.current.toFixed(1) + d.current_suffix;}
});
var rectangle1 = svgContainer.append("rect")
.attr("class","outerRect9")
.attr("x", outerRectDistFromLeft)
.attr("y",outerRectTopYPosition)
.attr("width", outerRectWidth)
.attr("height", OuterRectHeight)
.attr("fill", "url(#grad1)");
svgContainer.append("text")
.attr("y", margin.top + HeightForTopLabel -2 )
.attr("fill",
function(d){
var colorChange="";
if(d.change>=0.0)
colorChange="#06C10C";
else
colorChange="#F7063A";
return colorChange;
}
)
.attr("font-size",fontsize)
.text(function(d) {
if( d.change == null){
d3.select(this).attr("fill","black");
d3.select(this).attr("x",outerRectDistFromLeft + outerRectWidth/5 + 7);
return "N/A";
}else{
var pre ="";
if(d.change>=0.0)
pre="+";
/*if(d.current!=null)
{
d3.select(this).attr("x", outerRectDistFromLeft + outerRectWidth/5+3 );
}*/
var xposition = outerRectDistFromLeft + outerRectWidth/5;
/* if(d.current =! null){
d3.select(this).attr("x", xposition);
}
else
{
d3.select(this).attr("x", xposition);
}*/
d3.select(this).attr("x", xposition);
return pre+d.change.toFixed(1)/*+d.change_suffix*/;}
});
var rectangle0=svgContainer.append('rect') .attr("x", innerRectDistFromLeft)
.attr("y",outerRectTopYPosition).attr('width',8).attr('height',OuterRectHeight)
.attr('fill','#BDBDB7').attr('opacity',0.5);
var rectangle2=svgContainer.append('rect') .attr("x", innerRectDistFromLeft)
.attr("y", function(d) {
if(d.current == null){return (margin.top + HeightForTopLabel +OuterRectHeight);}
else{ return (margin.top + HeightForTopLabel +OuterRectHeight) - ((d.current/maxVal)*OuterRectHeight);}
}).attr('width',8).attr('height',function(d) {
if(d.current == null){
return 0;
}
else{ return ((d.current/maxVal)*OuterRectHeight);}
}).attr('fill',function(d,i){return d.color_code;});
var data1 = d3.range(5)
var c = d3.scale.ordinal()
.domain(data1)
.rangeBands([outerRectBottomYPosition + 1.5 ,outerRectTopYPosition ])
var innerRect= svgContainer.selectAll('.inners')
.data(data1)
.enter()
.append('rect').attr('class','inners')
.attr('y',function(d) { return (c(d));/*return Math.round(c(d))*/ })
.attr('x',innerRectDistFromLeft )
.attr('width',8)
.attr('height',(OuterRectHeight/5) )/*+ (1.5*3)*/
.style('stroke','#F6F6F6')
.style('stroke-width','1.2')
.style('fill', "none");
svgContainer.append("text")
.attr("x",function(d,i){
var name =d.name;
var lengthOfText = name.length;
if(lengthOfText > 2){
return outerRectDistFromLeft + outerRectWidth/3 - lengthOfText*2;
}
else {
return outerRectDistFromLeft + outerRectWidth/3;
}
} )
.attr("y", BottomTextYPosition)
.attr("font-size",fontsize)
.text(function(d) {
return d.name;
})
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut);
function handleMouseOver(d, i) {
creatSvg.append("rect").attr({
id: "tooltipvaluebox",
y: BottomTextYPosition,
height: 20,
fill:"#CACACE",
})
.attr("x",function(){
var len = (d.fullName.length*10)+20;
var val = newWidth*i;
if((val+len)>width){
var diff = (val+len) - width;
val = val - (diff+5);
}
return val+8;
} )
.attr("width",function(){
var len = d.fullName.length;
return (len*10)+20;
});
creatSvg.append("text").attr({
id: "tooltipvalue",
y: BottomTextYPosition+15
})
.attr("x",function(){
var len = (d.fullName.length*10)+20;
var val = newWidth*i;
if((val+len)>width){
var diff = (val+len) - width;
val = val - (diff+5);
}
return val+8;
} )
.text(function() {
return d.fullName ;
})
.attr('fill','black')
.style("font-family", "roboto");
};
function handleMouseOut(d, i) {
d3.select("#tooltipvaluebox").remove();
d3.select("#tooltipvalue").remove();
};
Chrome Version 66 for Windows seems to have a critical Bug in the DEV Engine. I think it's related to the meltdown hotfix in version 66. Its already fixed in Dev Channel V 68.x
I have multiple firebase items that I am looping through and they have name, categoryId, lat, lon.
I am trying to calculate a distance from 2 lat,lon (one is the one in firebase), the other is the user's location.
All of this is fine, and I can calculate it fine too. However, how do I inject/map the new variable into the firebase array that I am subscribed to?
this.categoryId = this.navParams.get('categoryId');
afoDatabase.list('/list', {query: {
orderByChild: "categoryId",
equalTo: parseInt(this.categoryId)
}}).subscribe(listItems => {
this.items = listItems; //need to add distance within array
loadingPopup.dismiss().catch(() => {});
});
For example, I have a variable called distance, that calculates everything and has the value. How do I add it in the this?items - so I can call it from the HTML side?
Thanks for the help :)
To inject, first create a function and create a variable (e.g. this.distance) and get the value of your function on this variable. After that use a for loop to increment, based on length - and use this.items[i]["distance"] to add to each one. For example:
this.categoryId = this.navParams.get('categoryId');
afoDatabase.list('/list', {query: {
orderByChild: "categoryId",
equalTo: parseInt(this.categoryId)
}}).subscribe(listItems => {
this.items = listItems;
this.geolocation.getCurrentPosition({timeout:15000}).then((resp) => {
this.myLat = resp.coords.latitude;
this.myLong = resp.coords.longitude;
}).catch((error) => {
console.log('Error getting location', error);
});
for (var i = 0, len = this.items.length; i < len; i++) {
this.distance = this.calculateDistance(this.myLat, this.myLong, this.items[i].lat, this.items[i].lng);
this.items[i]["distance"] = Math.round(this.distance);
console.log('testing myLat', this.myLat)
console.log('testing myLong', this.myLong)
}
console.log('testing inject', this.items)
loadingPopup.dismiss().catch(() => {});
});
Function
calculateDistance(lat1:number,lon1:number,lat2:number,lon2:number){
let R = 6371; // km
let dLat = (lat2 - lat1) * Math.PI / 180;
let dLon = (lon2 - lon1) * Math.PI / 180;
let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
let d = R * c;
return d;
}
I'm trying to get the distance between the records and the user's position. And order it by the one closest to me.
I'm using a formula similar to hacersine, but I still do not get the distance. Thanks.
My code html:
<div ng-app="my-app" id="por_logo.html">
<ons-page ng-controller="PorlogoCtl">
<div class="cliente" ng-repeat="cliente in porlogo.clientes" ng-if="cliente.estado == '1'">
<p>{{cliente.nombre}} <span>{{distancia2}}</span></p>
</div>
</ons-page>
</div>
Similar to haversine:
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6878; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI/180)
};
Code JS:
var app = angular.module('my-app', ['onsen']).factory('position', function( $rootScope ){
// console.log('building position')
var position = {};
// 1ST / AUTO GEOLOCATION OF USER
// displays a popup to indicate current user location - (disabled)
// onSuccess Callback - This method accepts a Position object, which contains the current GPS coordinates
var onSuccess = function(position2) {
console.log(position2.coords.latitude )
console.log(position2.coords.longitude)
position.latitude = position2.coords.latitude;
position.longitude = position2.coords.longitude;
$rootScope.$digest()
};
function onError(error) { // onError Callback receives a PositionError object
// alert('code: ' + error.code + '\n' +
// 'message: ' + error.message + '\n');
alert('No podemos acceder a su ubicaciĆ³n');
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
return position;
});
app.controller("PorlogoCtl", function($scope, $http, position, $rootScope) {
$http.get('https://viveenunclick.com/api.php/clientes?transform=1').
success(function(data, status, headers, config) {
$scope.porlogo = data;
$rootScope.latitude = position.latitude;
$rootScope.longitud = position.longitude;
$rootScope.distancia2 = getDistanceFromLatLonInKm(position.latitude,position.longitude,$rootScope.latitude,$rootScope.longitud).toFixed(1);
console.log($rootScope.longitud);
}).
error(function(data, status, headers, config) {});
});
Post Demo in Codepen
the coordinates are in the data returned, you will get it by: $scope.porlogo[iteration].Latitud & $scope.porlogo[iteration].Longitud
So to have theses, you need to iterate. You could use the iteration in the view:
<p>{{cliente.nombre}} <span>{{distancia(cliente)}}</span></p>
and in your controller, add this distancia function to return the right distance:
Important: But if you need to use toFixed(1) which return a string (order will be by a string), you need to add parseFloat() so it will return a number and order will be right.
$scope.distancia = function(item) {
//it's item.Latitud & item.Longitud, from the data
return parseFloat(getDistanceFromLatLonInKm(position.latitude,position.longitude,item.Latitud,item.Longitud).toFixed(1));
}
You can use this function too for the sort & order,
<div class="cliente" ng-repeat="cliente in porlogo.clientes | orderBy: distancia: false">
Working pen
I need to recalculate some values inside scope object on form submit.
So i've got:
$scope.submit = function() {
if ($scope.searchPlace) {
var address = $scope.searchPlace + ', ' $scope.land;
geocodeAddress(address, function(latLng){
angular.forEach($scope.places,function(value,key){
var distance = getDistance(value.latitude,value.longitude,latLng.lat(),latLng.lng())
value.distance = distance;
});
});
}
};
$scope.places is something like [{'name':'place_a', 'distance': 0}, {'name':'place_b', 'distance': 0}]
But I can not see any changes to scope object in frontend. What am I missing?
Here are both functions used above
var getDistance = function(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
var geocodeAddress = function(address, callback) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
callback(results[0].geometry.location);
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
};
If getDistance function returns a promise, you should use it like this :
getDistance(value.latitude,value.longitude,latLng.lat(),latLng.lng()).then(function(response){
var distance = response.data;
value.distance = distance;
});
I am trying to push mixpanel data into a single Google Sheet using code from here:
https://github.com/melissaguyre/mixpanel-segmentation-google-spreadsheets
I am having issues with the API_PARAMETERS not looping through as expected. (Formula, Formula1, & Formula2) The first two parameters loop through fine, but when the final is added, I get the error:
TypeError: Cannot read property "2016-07-11" from undefined. (line 143, file "Code")
Here is the code:
* Step 1) Fill in your account's Mixpanel Information here
`enter code here`*/
var API_KEY = '******';
var API_SECRET = '****';
/**
* Step 2) Define the tab # at which to create new sheets in the spreadsheet.
* 0 creates a new sheet as the first sheet.
* 1 creates a new sheet at the second sheet and so forth.
*/
var CREATE_NEW_SHEETS_AT = 0;
/**
* Step 3) Define date range as a string in format of 'yyyy-mm-dd' or '2013-09-13'
*
* Today's Date: set equal to getMixpanelDateToday()
* Yesterday's Date: set equal to getMixpanelDateYesterday()
*/
var FROM_DATE = getMixpanelDate(7);
var TO_DATE = getMixpanelDate(1);
/**
* Step 4) Define Segmentation Queries - Get data for an event, segmented and filtered by properties.
var API_PARAMETERS = {
'Formula' : [ 'QuestionAsked', '(properties["InputMethod"]) == "Voice" or (properties["InputMethod"]) == "Text" ', 'general', 'day', 'B7'],
'Formula1' : [ 'QuestionAsked', '(properties["InputMethod"]) == "Voice" or (properties["InputMethod"]) == "Text" ', 'unique', 'day', 'B2'],
//'Formula2' : [ 'QuestionAnswered', '(properties["InputMethod"]) == "Voice" or (properties["InputMethod"]) == "Text" ', 'unique', 'day', 'B3' ],
};
// Iterates through the hash map of queries, gets the data, writes it to spreadsheet
function getMixpanelData() {
for (var i in API_PARAMETERS)
{
var cell = API_PARAMETERS[i][4];
fetchMixpanelData(i, cell);
}
}
// Creates a menu in spreadsheet for easy user access to above function
function onOpen() {
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
activeSpreadsheet.addMenu(
"Mixpanel", [{
name: "Get Mixpanel Data", functionName: "getMixpanelData"
}]);
}
/**
* Gets data from mixpanel api and inserts to spreadsheet
*
*/
function fetchMixpanelData(sheetName, cell) {
var c = cell;
var expires = getApiExpirationTime();
var urlParams = getApiParameters(expires, sheetName).join('&')
+ "&sig=" + getApiSignature(expires, sheetName);
// Add URL Encoding for special characters which might generate 'Invalid argument' errors.
// Modulus should always be encoded first due to the % sign.
urlParams = urlParams.replace(/\%/g, '%25');
urlParams = urlParams.replace(/\s/g, '%20');
urlParams = urlParams.replace(/\[/g, '%5B');
urlParams = urlParams.replace(/\]/g, '%5D');
urlParams = urlParams.replace(/\"/g, '%22');
urlParams = urlParams.replace(/\(/g, '%28');
urlParams = urlParams.replace(/\)/g, '%29');
urlParams = urlParams.replace(/\>/g, '%3E');
urlParams = urlParams.replace(/\</g, '%3C');
urlParams = urlParams.replace(/\-/g, '%2D');
urlParams = urlParams.replace(/\+/g, '%2B');
urlParams = urlParams.replace(/\//g, '%2F');
var url = "http://mixpanel.com/api/2.0/segmentation?" + urlParams;
Logger.log("THE URL " + url);
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var dataAll = JSON.parse(json);
var dates = dataAll.data.series;
Logger.log(API_PARAMETERS);
for (i in API_PARAMETERS){
var parametersEntry = API_PARAMETERS[i];
for (i in dates){
data = dataAll.data.values[parametersEntry[0]][dates[i]];
}
insertSheet(data, c);
};
}
function insertSheet(value, cell) {
var sheetName = 'Formula';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var c = sheet.getRange(cell).setValue(value);
};
/**
* Returns an array of query parameters
*/
function getApiParameters(expires, sheetName) {
var parametersEntry = API_PARAMETERS[sheetName];
return [
'api_key=' + API_KEY,
'expire=' + expires,
'event=' + parametersEntry[0],
'where=' + parametersEntry[1],
'type=' + parametersEntry[2],
'unit=' + parametersEntry[3],
'from_date=' + FROM_DATE,
'to_date=' + TO_DATE
];
}
/**
* Sorts provided array of parameters
*
function sortApiParameters(parameters) {
var sortedParameters = parameters.sort();
// Logger.log("sortApiParameters() " + sortedParameters);
return sortedParameters;
}
/**
function getApiExpirationTime() {
var expiration = Date.now() + 10 * 60 * 1000;
// Logger.log("getApiExpirationTime() " + expiration);
return expiration;
}
/**
* Returns API Signature calculated using api_secret.
*/
function getApiSignature(expires, sheetName) {
var parameters = getApiParameters(expires, sheetName);
var sortedParameters = sortApiParameters(parameters).join('') + API_SECRET;
// Logger.log("Sorted Parameters " + sortedParameters);
var digest = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, sortedParameters);
var signature = '';
for (j = 0; j < digest.length; j++) {
var hashVal = digest[j];
if (hashVal < 0) hashVal += 256;
if (hashVal.toString(16).length == 1) signature += "0";
signature += hashVal.toString(16);
}
return signature;
}
/**
*********************************************************************************
* Date helpers
*********************************************************************************
*/
// Returns today's date string in Mixpanel date format '2013-09-11'
function getMixpanelDateToday() {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if ( mm < 10 ) {
mm = '0' + mm;
}
today = yyyy + '-' + mm + '-' + dd;
return today;
}
// Returns yesterday's's date string in Mixpanel date format '2013-09-11'
function getMixpanelDate(days){
var today = new Date();
var d = new Date(today);
d.setDate(today.getDate() - days);
//Logger.log(yesterday);
var dd = d.getDate();
//Logger.log(yesterday);
var mm = d.getMonth() + 1;
var yyyy = d.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
d = yyyy + '-' + mm + '-' + dd;
//Logger.log(yesterday);
return d;
}