how to access dates stored inside the an indicator object? - javascript

i have a map application, and in the interface, there a combo box contains 5 indicators(HDI, Life Expectancy, ..,..,..). I checked the 'data' of each indicator using FireBug 1.9.2, and I found that, inside the 'data' of each indicator the name of the indicator is listed and inside it there is a list of dates something like (1960.....up to 2010) some of these dates contains data according to its corresponding indicator and some of these dates contains no data "".
What i want to do is, to check the dates of each indicator and if the date contains data or value, i want to store that date otherwise do nothing with the date.
please see the snap shots i post maybe it would give clearer perception about what i want to do.
also please see how i tried to achieve this goal, but unfortunately the result is not what i want:
function getYearsByIndicator(layername, indicator) {
var matchingLayers;
var vectorLayer;
var yearStore;
// get vector layer
matchingLayers = map.getLayersByName(layername);
if (matchingLayers.length == 1) {
vectorLayer = matchingLayers[0];
}
else {
console.log("getThematicStyleMap: Warning, the layer " + layername + " was not found!");
return;
}
for (var i=0;i < vectorLayer.features.length;i++) {
if (vectorLayer.features[i]['data'][indicator]) {
// extract keys here!
}
}
//build store containing the extracted keys
//return the store
return yearStore;
}

Since its an object, I guess you can access it by:
$data->{propertyname}
EDIT: I was confused, I guess you are using javascript instead of PHP (which is one of your tags). When you are using javascript, you can access the values like your accessing arrays, so variable["property"]["subproperty"] etc
EDIT2: You can check it using
if(data["HDI"][1980] != "")
{
//date is not empty
}
EDIT3: Iterate over the content by using:
for(var key in data["HDI"])
{
//Key is 1980 etc
if(data["HDI"][key] != "")
{
//Date is not empty
}
}

Related

Reordering/move pages using Indesign script

I have a nearly 400 page document that I need to [randomly] reorder the pages. (If you need to know, this is a book of single page stories that need to be randomly distributed. I created a random list of pages to input into the script.)
I've been working with a modified script I found elsewhere on the internet that creates an array and moves the pages around:
var order="...list of new page numbers...";
// Create an array out of the list:
ranges = toSeparate (order);
if (ranges.length != app.activeDocument.pages.length)
{
alert ("Page number mismatch -- "+ranges.length+" given, "+app.activeDocument.pages.length+" in document");
exit(0);
}
// Consistency check:
sorted = ranges.slice().sort(numericSort);
for (a=0; a<sorted.length-1; a++)
{
if (sorted[a] < sorted[a+1]-1 ||
sorted[a] == sorted[a+1])
alert ("Mismatch from "+sorted[a]+" to "+sorted[a+1]);
}
// alert ("New order for "+order+"\nis "+ranges.join(", "));
// Convert from 1..x to 0..x-1:
for (moveThis=0; moveThis<ranges.length; moveThis++)
ranges[moveThis]--;
for (moveThis=0; moveThis<ranges.length; moveThis++)
{
if (moveThis != ranges[moveThis])
{
try{
app.activeDocument.pages[ranges[moveThis]].move (LocationOptions.BEFORE, app.activeDocument.pages[moveThis]);
} catch(_) { alert ("problem with page "+moveThis+"/index "+ranges[moveThis]); }
}
for (updateRest=moveThis+1; updateRest<ranges.length; updateRest++)
if (ranges[updateRest] < ranges[moveThis])
ranges[updateRest]++;
}
function toSeparate (list)
{
s = list.split(",");
for (l=0; l<s.length; l++)
{
try {
if (s[l].indexOf("-") > -1)
{
indexes = s[l].split("-");
from = Number(indexes[0]);
to = Number(indexes[indexes.length-1]);
if (from >= to)
{
alert ("Cannot create a range from "+from+" to "+to+"!");
exit(0);
}
s[l] = from;
while (from < to)
s.splice (++l,0,++from);
}} catch(_){}
}
// s.sort (numericSort);
return s;
}
function numericSort(a,b)
{
return Number(a) - Number(b);
}
This code worked, except that it was consistently rearranging them into the wrong random order, which, at the end of the day, is workable, but it'll just be a bigger pain in the ass to index the stories.
I suspected the problem might be caused by starting at the begginning of the document rather than the end, so I modified the script to start at the end, but then app.activeDocument.pages[ranges[moveThis]] kept coming up as undefined.
So I gave up and tried this:
app.activeDocument.pages[298].move (LocationOptions.BEFORE, app.activeDocument.pages[366]);
app.activeDocument.pages[33].move (LocationOptions.BEFORE, app.activeDocument.pages[365]);
app.activeDocument.pages[292].move (LocationOptions.BEFORE, app.activeDocument.pages[364]);
And so on for every page. (This reminds me of my time in junior high using sendKeys to create programs in Visual Basic. Had I bothered to seriously learn JavaScript instead of creating shitty AOL chatroom scrollers, I probably wouldn't be on here today.)
Nevertheless, I received the following error:
Error Number: 30477
Error String: Invalid value for parameter 'reference' of method 'move'. Expected Page or Spread, but received nothing.
I'm trying to avoid having to manually move the pages, especially considering the amount of time I've already been working on this. Any suggestions on what I need to change? Thank you!
The issue might be that you are using more than one page per spread and then trying to shuffle them across spread. The better way is to use single page per spread.
Here is a small snippet that works on my machine
var doc = app.activeDocument;
doc.documentPreferences.facingPages = false;
for (var i =0; i < 100; i++){
var index = parseInt((Math.random() * doc.spreads.length) % doc.spreads.length + '' , 10);
doc.spreads[index].move();
}
What this does is
Disables the facing pages options and makes one page per spread. A desirable condition as you mentioned that your stories are one page each(I am assuming that your stories will not violate this assumption).
Takes a random spread from the doc and sends it to the end of the spreads in the doc. It does so 100 times.
The result is what you wanted. A script to shuffle the current SPREADS randomly.

Set Qualtrics Embedded Data with Javascript for loop

I am working on a survey in qualtrics, and need to be able to set many embedded data fields with different values, depending on a random selection of the experimental condition.
In the Survey Flow, I've entered all the names of the desired embedded data values.
I want this code to execute at the start of the survey, and to go through and set the values of those Embedded data variables.
The reason I use a for loop is because the variables are named things like:
set1a
set1b
set1c
var condition = Math.floor((Math.random() * 3) + 1)
var conditions =[ [8,8,8,5,5,5,5,2,2,2], [8,8,8,7,7,7,7,2,2,2], [10,10,10,5,5,5,5,2,2,2], [10,10,10,7,7,7,7,2,2,2]]
var values = condition[conditions]
var letters ="abcdefghij"
Qualtrics.SurveyEngine.addOnload(function(values)
{
for (var i = 0; i < values.length; i++ ) {
var dataname = "set1" + letters.charAt(i)
Qualtrics.SurveyEngine.setEmbeddedData(dataname,values[i]);
}
});
However, this code doesn't work.
When I try to call the variables using piped text later on in the survey (after a page break) they do not appear to have stored.
You have two issues.
First, you can only set Javascript in Qualtrics if it's inside of the .addOnload function, e.g.:
Qualtrics.SurveyEngine.addOnload(function(values)
{
// Your code
});
Second, your method for assigning - values - throws an error message.
Qualtrics doesn't have an issue saving embedded data in a for loop, so if you fix these two points, you should be good to go.

Pulling JSON into Google Sheet via API resulting in undefined values in cells

I have an issue with one of my API's I am trying to establish an API to call on a Customer Relationship Management tool called Streak, I am attempting to pull data via a HTTP Basic Auth GET which parses a JSON file through my script logic and then into my Google Sheets spreadsheet. The Google App Script after a few hours of development is working flawlessly (for my requirements) par one thing, my script is inserting the string 'undefined' into my google sheet cells whenever it cannot locate a value, a completely empty non existent field.
Image of Google Sheet Output issue can be seen below
Note: I have highlighted both the field property names and undefined values that are causing me grief
https://drive.google.com/file/d/0B4rXaBEqs2UzSU5fMFUxYW8zTm8/view?usp=sharing
The entire Code Snippet that is ran to extrapolate hundreds of records to my Google Sheet can be seen below. From my understanding my problem is within the statement row.push(field 1001 -> 1021), it is always attempting to push all fields to the sheet; however, not all records contain these fields as I may not have populated them within the source CRM. In response to this the script is populating "undefined" strings in the corresponding cells within my Sheet.
I am hoping to prevent this "undefined" string from being populated in the sheet, instead of this the cell should be blank, can someone please advise how I can tweak my code snippet to achieve this? Much appreciated! I have tried for nearly 2-3 hours to work around this issue but I am not experienced enough to find the answer, I have tried various IF statements and looked into defining variable types (i.e. integer, floating, char etc) none of which seem to work. I am sure a solution is simple once you know it, your assistance is greatly appreciated!
//Within this API we need to achieve collecting my data from Streak CRM us
//
// Notes on Google API
// https://developers.google.com/apps-script/guides/services/external
//
// Notes on Streak API
// https://www.streak.com/api/
//
//API Key YOUR_API_KEY Here
function myStreak() {
//Google Sheet Data
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheet = ss.getSheetByName("StreakCRM");
//Streak API Call
var consumerKey = 'YOUR_API_KEY_HERE'
var url = "https://www.streak.com/api/v1/boxes";
var headers = {
"contentType": "application/json",
"headers":{
"User-Agent": "MY_APP_NAME (App URL/your email address)",
"Authorization": "Basic " + Utilities.base64Encode(consumerKey)
},
"validateHttpsCertificates" :false
};
//Fetch Streak Data
var response = UrlFetchApp.fetch(url, headers);
var dataAll = JSON.parse(response.getContentText());
//Write Captured Streak Data to Google Sheet
var dataSet = dataAll;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([data.name,
data.stageKey,
// data.fields['1001'], empty field
data.fields['1002'],
data.fields['1003'],
// data.fields['1004'], empty field
data.fields['1005'],
data.fields['1006'],
data.fields['1007'],
data.fields['1008'],
data.fields['1009'],
data.fields['1010'],
data.fields['1011'],
data.fields['1012'],
// data.fields['1013'], empty field
data.fields['1014'],
data.fields['1015'],
// data.fields['1016'], empty field
data.fields['1017'],
data.fields['1018'],
data.fields['1019'],
// data.fields['1020'], empty field
data.fields['1021'],
data.fields['1023']]);//your JSON entities here
}
dataRange = sheet.getRange(3, 1, rows.length, 19); // 19 Denotes total number of entites
dataRange.setValues(rows);
//Capture response code success or errors
var text = response.getResponseCode();
Logger.log(text);
Logger.log(response);
}
You've already accepted a good answer but if I could offer an alternative modified approach.
//Write Captured Streak Data to Google Sheet
var dataSet = dataAll,
rows = [],
data,
dataFields = ['name', 'stageKey', '1001' … ]; //include all the JSON fields you want to transfer including any deliberate blanks you don't exist.
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push(dataFields.map(function (f) {
return data[f] || '';
});
}
The point here is to control the direct mapping of data fields once at the outset.
At the end of the loop then you'll see another alternative to the ternary if thrown in for good measure.
return data[f] || '';
Which is in the form
var foo = bar || 'default';
|| is the OR you know from if statements. In effect this pattern says "let foo be bar unless it is falsey in which case use 'default'.
This is the expected behaviour, since those properties are missing entirely from a given row of data, they are undefined variables. When you write an undefined variable to a sheet, it is converted into the string "undefined".
To handle this, you should do a check on each property name to make sure it exists, and if it doesn't use a desired default value instead.
You mentioned you tried various If statements. The way to check if a value is specifically undefined is to do:
if(data.fields['somefieldname'] === undefined)
However, usually you just want to know if the value evaluates to false, in which case you can simply do:
if(data.fields['somefieldname'])
Which will evaluate as False if data.fields['somefieldname'] is any value that evaluates to false, such as null, false, 0 or undefined, and true for any other value.
Finally, since if statements are a bit long for this particulay usage, I suggest using the "Conditional Operator" or "Ternary Operator" to handle this in your code:
( (data.fields['1002'])? data.fields['1002'] : '' )
Which can be read as "if data.fields['1002'] is true, return data.fields['1002'], else return empty string"
Here is some documentation on the the Conditional Operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
In a snippit of your code, it would look like this:
rows.push([data.name,
data.stageKey,
// data.fields['1001'], empty field
(data.fields['1002'])?data.fields['1002']:'',
(data.fields['1003'])?data.fields['1002']:'',
...
...
]);
You can specify any value for the "else" condition, a 0 instead of an empty string, for example.

using try catch when declaring variables

For one reason or other ( I'm not going to go into why here) I need to use javascript to get the values of 12 hidden input fields and set a variable for each value.
I am not sure what the best approach for this would be. I'd like to be able to get the values and if they are not created i.e. the input fields are not there then id like to generate an error.
Would using a try / catch be good for this or should I simply be using typeof to check the variables have been created?
would putting them in an array as well so i can loop through to check their existance be a good idea?
thanks
This is the easy way of doing it. try-catch is rather heavy. Also, where would you throw the error to? Instead of unwinding your flow on error, collect your errors into a well structured response. That way if your first one is missing, but the other X are not, then you still get some work done.
if ( typeof( something ) !== "undefined" ) { doStuff(); }
Otherwise, I'd need more information to help you with your question.
Here's simple function that will check to see that exactly 12 input elements are included on the page. Please provide more information if you need th check that individual input elements are present.
function SaveInputValues() {
var inps = document.getElementsByTagName('input');
if (inps.length !== 12) {
return alert("There must be exactly 12 input elements. You have included " + inps.length + ".");
}
var vals = [];
for (i = 0; i < inps.length; i++) vals.push(inps[i].value);
inps = null; // provides closure
}
if(document.getElementById("someID")){
// add the value since the input exists
}
else{
// skip or use default - and inform if need be
}
Example implementation:
http://jsfiddle.net/zVz6h/1/
Code:
function getValueArray(idArray){
var valArray = [];
for(var i=0;i<idArray.length;i++){
if(document.getElementById(idArray[i])){
valArray.push(document.getElementById(idArray[i]).value);
}
else{
valArray.push("not defined");
}
}
return valArray;
}
var txtIDs = ["txt1","txt2","txt3","txt4","txt5","txt6","txt7","txt8"];
alert(getValueArray(txtIDs));

How to access key itself using javascript

I have a JSON like:
var xx = {'name':'alx','age':12};
Now I can read the value of name which is 'alx' as xx[0].name, but how should I retrieve value of 'name' itself? By that, I mean how can I fetch the key at run time?
for (i in xx) {
if (xx[i] == "alx") {
// i is the key
}
}
modified Code (from Victor) taking into account that you might want to look for any other possible string
var search_object = "string_to_look_for";
for (i in xx) {
if (xx[i] == search_object) {
// i is the key
alert(i+" is the key!!!"); // alert, to make clear which one
}
}
You are looking for associative arrays in Javascript. A quick google search suggests the following:
Read this page http://www.quirksmode.org/js/associative.html
and especially this section http://www.quirksmode.org/js/associative.html#link5

Categories

Resources