Take the tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to create array from an API output. And then filter the array down to one item designated by the itemID. Below is my attempt at it. I am getting an error that jsonArray isn't present in function test. I presume I need to make it a global variable or something, but that is where I hit a wall.

function onOpen() {
var myUrl = "http://www.gw2spidy.com/api/v0.9/json/all-items/all"
var jsonData = UrlFetchApp.fetch(myUrl);
var jsonArray = JSON.Parse(jsonData);
return jsonArray
}

function test(itemID) {
var jsonFilter = jsonArray.filter(function(itemID){return itemID.data_id==itemID});
var jsonObject = JSON.parse(jsonFilter).result;
var adjustedValue = (jsonObject.min_sale_unit_price / 100);
return adjustedValue;
}

I previously had it working with the following code (ripped from someone else), but each use of that function made a call. I am trying to reduce the number of calls to one call per sheet refresh (this is in the google docs script manager).

// function to return the current sell value for an item (designated by
 // the item’s ID number) from GW2Spidy's API formatted with copper in
 // the tens and hundreds places
function getItemSellValue(itemID) {
 // base URL for the API that will return JSON for the itemID supplied
var myUrl = "http://www.gw2spidy.com/api/v0.9/json/item/" + escape(itemID);
 // fetches the information from the URL in an HTTPResponse
var jsonData = UrlFetchApp.fetch(myUrl);
 // now we convert that response into a string so that we can use it
var jsonString = jsonData.getContentText();
 // now, we turn it into a Javascript object for easier handling
 // *note: I also remove the "result" wrapper object so we can
 // use direct calls on the objects parameters
var jsonObject = JSON.parse(jsonString).result;
 // now I divide the value by 100 in order to format it more like
 // currency. (ie. 126454, which equals 12 gold, 64 silver,
 // and 54 copper will now be displayed as
 // 1264.54)
var adjustedValue = (jsonObject.min_sale_unit_price / 100);
 // finally we return the adjusted min sell value
return adjustedValue;
}

Update I updated the code dropping the onOpen() and switching to the cache service. I am receiving the following error now: "error: Argument too large: value (line 12, file "gwspidy api")". Line 12 is cache.put("gw2spidy-data", jsonData, 1500); Is it just the size of the data? I don't know how much I can filter it down. The full code is below.

function test(itemID) {
  var cache = CacheService.getPublicCache();
  var cached = cache.get("gw2spidy-data");
// check if the data is cached and use it if it is
  if (cached != null) {
    var jsonData = cached
    }
//otherwise fetch the data and cache it
  else {
    var myUrl = "http://www.gw2spidy.com/api/v0.9/json/all-items/all"
    var jsonData = UrlFetchApp.fetch(myUrl);
    cache.put("rss-feed-contents", jsonData, 1500);
    }
//put data into an array and filter the result down to the given id, then return the function value
  var jsonArray = JSON.Parse(jsonData);
  var jsonFilter = jsonArray.filter(function(itemID){return itemID.data_id==itemID});
  var jsonObject = JSON.parse(jsonFilter).result;
  var adjustedValue = (jsonObject.min_sale_unit_price / 100);
  return adjustedValue;  
}
share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

It looks like you've got a few ideas crossing over, causing you problems.

  • The object jsonArray is declared within the scope of the function onOpen(), and is out of scope for test().

  • An onOpen() trigger function is a simple trigger, when it is in a spreadsheet or document container-bound script. It's not clear from your question or code whether this script is in one or the other, or a standalone script.

  • An onOpen() function doesn't need to return anything - the event manager that invokes it will ignore any value returned. This isn't a mechanism for making a value available outside the scope of the function.

  • If your intent is to have the onOpen() function populate an object that can be used by other functions, then you're right to think about a global1... but you will instead need to use some other mechanism to share the value. (Look into the Cache Service - it is perfect for this.)


1 Each separate execution of a script is done in a new execution instance. Any variables defined outside of a block of code (aka "global" variables) are therefore unique for that instance. When a trigger function is invoked by an event, it runs in its own instance, and any global values it sets are visible only to that instance; another function that is invoked by a spreadsheet or document UI, for example, would have its very own version of that non-scoped object (global).

share|improve this answer
 
Perfect, you read my mind! Sorry for the unclear question as my javascript is relatively green and it was late at night! :) I updated my question with additional code using the cache service that you suggested. –  Jacob Bolda Aug 4 at 2:12
 
Ok, instead Of filtering It Down, I Can Just Grab A portion Since I Only Need The Min_Sale_Unit_Price. Correct? Sorry About All The Caps, My Phone Autocaps Everything And I Cant Stop it. –  Jacob Bolda Aug 4 at 17:14
 
Yep - restricting the content to just the bit you need will help. –  Mogsdad Aug 8 at 17:43
 
After a few iterations, I ended up doing just that. I posted another question here if you could help! stackoverflow.com/questions/18131752/… –  Jacob Bolda Aug 8 at 18:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.