returning nested json values using loop (google spreadsheet) - javascript

I have this google spreadsheet script that pulls in json formatted book data. I have no problem displaying book title and author, but he "offerData" object can contain a different amount of elements (prices from sellers) depending on the book. Right now I created a loop and am storing the offerData values like so:
price[i] = offerdata.offers[i]["price"];
condition[i] = offerdata.offers[i]["condition"];
seller[i] = offerdata.offers[i]["seller"]["displayName"];
and am returning the data like this:
var resultRow = [[title, specstag, price[0], condition[0], seller[0], price[1], condition[1], seller[1], price[2], condition[2], seller[2]]];
Obviously this only returns 3 sellers with price, condition, seller info. The issue is that a book doesn't always have 3 sellers, it can be anywhere from 1 to 10 or so.
My question is how can I return all offerData (price/condition/seller) here? :
var resultRow = [[title, specstag, price[0], condition[0], seller[0], price[1], condition[1], seller[1], price[2], condition[2], seller[2]]];
--
function getBookDetails(isbn) {
// Query the book database by ISBN code.
if (isbn !== "") {
var url = "https://api.bol.com/catalog/v4/search/?apikey=myapi6&offers=all&format=json&q=" + isbn;
var response = UrlFetchApp.fetch(url);
var results = JSON.parse(response);
if (results.totalResultSize) {
// There'll be only 1 book per ISBN
var book = results.products[0];
// get Title and Authors
var title = (results.products[0]["title"]);
var specstag = (results.products[0]["specsTag"]);
var offerdata = results.products[0]["offerData"];
if (typeof offerdata.offers !== 'undefined' && offerdata.offers.length > 0) {
var arrayLength = offerdata.offers.length;
var price = [];
var condition = [];
var seller = [];
for (var i = 0; i < arrayLength; i++) {
price[i] = offerdata.offers[i]["price"];
condition[i] = offerdata.offers[i]["condition"];
seller[i] = offerdata.offers[i]["seller"]["displayName"];
}
}
}
var resultRow = [[title, specstag, price[0], condition[0], seller[0], price[1], condition[1], seller[1], price[2], condition[2], seller[2]]];
return resultRow;
}
}

the answer
var resultRow = [];
resultRow[0] = [];
resultRow[0][0]=title;
resultRow[0][1]=specstag;
for (var i = 0; i < arrayLength; i=1+3) {
resultRow[0][3*i+2]=price[i];
resultRow[0][3*i+3]=condition[i];
resultRow[0][3*i+4]=seller[i];
}
how you should think about it is to see the index of the elements in the array and then find relation between i and the index you want
var resultRow = [
[
title, //[0][0]
specstag, //[0][1]
price[0], //[0][2]
condition[0], //[0][3]
seller[0], //[0][4]
price[1], //[0][5]
condition[1], //[0][6]
seller[1], //[0][7]
price[2], //[0][8]
condition[2], //[0][9]
seller[2]//[0][10]
]
];

You might be looking for something like this;
var data = { title: null,
spcstag: null,
pcs: [],
};
offerData.offers.forEach( p => { var pcsData = {};
!!data.title || data.title = p.title;
!!data.specstag || data.specstag = p.specstag;
pcsData.price = p.price;
pcsData.condition = p.condition;
pcsData.seller = p.seller;
data.pcs.push(pcsData);
});

Related

Concat in a for loop google app scripts javascript

I'm trying to filter in an array by data in another array using concat in a for loop. The elements of the following code are logging correctly, but the final array is logging an empty array.
function Shipments (){
var app = SpreadsheetApp;
var movementSS = app.getActiveSpreadsheet();
var infoSheet = movementSS.getSheetByName("Update Info");
var orderInfoSheet = movementSS.getSheetByName("Order Info");
var targetSheet = movementSS.getSheetByName("Shipments");
var ShipLogSS = app.openByUrl(URL).getSheetByName("Shipping Details");
var ShipArr = ShipLogSS.getRange(3,1,ShipLogSS.getLastRow(),ShipLogSS.getLastColumn()).getValues().
filter(function(item){if(item[1]!=""){return true}}).
map(function(r){return [r[0],r[1],r[2],r[4],r[10],r[11],r[16],r[18],r[23]]});
var supplierData = orderInfoSheet.getRange(3,6,orderInfoSheet.getLastRow(),1).getValues().
filter(function(item){if(item[0]!=""){return true}});
var supplierList = [];
for (var i in supplierData) {
var row = supplierData[i];
var duplicate = false;
for (var j in supplierList) {
if (row.join() == supplierList[j].join()) {
duplicate = true;
}
}
if (!duplicate) {
supplierList.push(row);
}
}
var supplierFilter = [];
for(var i = 0; i < supplierList.length; i++){
var shipments = ShipArr.filter(function(item){if(item[4]===supplierList[i][0]){return true}});
supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);
}
Any help would be greatly appreciated!
You need to assign the result of concat onto the supplierFilter in order to see the changes in later iterations and in the outer scope.
You can also return the comparison done inside the .filter callback immediately, instead of an if statement - it looks a bit cleaner.
var supplierFilter = [];
for (var i = 0; i < supplierList.length; i++) {
var shipments = ShipArr.filter(function (item) { return item[4] === supplierList[i][0]; });
supplierFilter = supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);

Javascript looping through variables

So right now this is my current code and I'm trying to figure out a way to loop through the variables I've already declared (Assuming variables 1-9 already have values). I just wanted to know whether this was possible at all?
var title;
var brief;
var hover;
var whatTitle;
var whatDesc;
var whyTitle;
var whyDesc;
var funTitle;
var funDesc;
var titles = [];
var briefs = [];
var hovers = [];
var whatTitles = [];
var whatDescs = [];
var whyTitles = [];
var whyDescs = [];
var funTitles = [];
var funDescs = [];
var obj = {'titles' : title};
if(localStorage.getItem('titles') != null) {
var tmp = JSON.parse(localStorage.getItem('titles'));
for(var i = 0;i<tmp.length;i++) {
titles.push(tmp[i]);
}
}
titles.push(obj);
localStorage.setItem("titles", JSON.stringify(titles));
Output I want if we printed out the looped code:
var obj = {'titles' : title};
if(localStorage.getItem('titles') != null) {
var tmp = JSON.parse(localStorage.getItem('titles'));
for(var i = 0;i<tmp.length;i++) {
titles.push(tmp[i]);
}
}
titles.push(obj);
localStorage.setItem("titles", JSON.stringify(titles));
var obj = {'briefs' : brief};
if(localStorage.getItem('briefs') != null) {
var tmp1 = JSON.parse(localStorage.getItem('briefs'));
for(var i = 0;i<tmp.length;i++) {
briefs.push(tmp[i]);
}
}
briefs.push(obj);
localStorage.setItem("briefs", JSON.stringify(briefs));
var obj = {'hovers' : hover};
if(localStorage.getItem('hovers') != null) {
var tmp2 = JSON.parse(localStorage.getItem('hovers'));
for(var i = 0;i<tmp.length;i++) {
hovers.push(tmp[i]);
}
}
hovers.push(obj);
localStorage.setItem("hovers", JSON.stringify(hovers));
...etc
If the code is running in a browser, then you can do something like:
for(key in window) { console.log(window[key]) } // print all variables
The variables are associated to the global namespace. That is to say the upmost "this" reference or the window object.
You're almost there with the code you have. If you look at your "desired output" examples, you'll see that the only thing that really differs between each element of your "unrolled loop" is the key for local storage ('titles', 'briefs', 'hovers').
With that in mind, you could use an Object to map the keys to the variables you have at the top level. So this:
var titles = [];
var briefs = [];
var hovers = [];
var whatTitles = [];
var whatDescs = [];
...
Becomes (UPDATE: with the initializer values preserved):
var key_to_collection = {
'titles': [title],
'briefs': [brief],
'hovers': [hovers],
'whatTitles': [whatTitles],
'whatDescs': [whatDescs],
}
Then, you loop over the values of this object:
Object.keys(key_to_collection).forEach(function(key) {
var obj = {};
collection = key_to_collection[key];
obj[key] = collection;
if(localStorage.getItem(key) != null) {
var tmp = JSON.parse(localStorage.getItem(key));
for(var i = 0;i<tmp.length;i++) {
collection.push(tmp[i]);
}
}
collection.push(obj);
localStorage.setItem(key, JSON.stringify(collection));
});
If your variable name is title for example, then you can access it using window['title']. This means that if you define an array of your global variable names:
const varNames = ['title', 'brief', 'hover', ...]
Then you can do a loop like the following
for(const name of varNames) {
const value = window[name]
// do whatever you want using the variable name and value
}
I hope this solves your issue :)

C# class only returning first item of a JavaScript array - cant update just one record of db

I have a grid in html with some data of example Directors. Then I change the data, and want to update db.
Using a JS function, I get all the details from the grid, and save it in an array.
function getDirectorGridDetails() {
var tableRows = document.getElementById("tc_directorsGrid_table").rows
for (var i = 0; i < tableRows.length; i++) {
var directorRow = tableRows[i]
if (directorRow) {
var directorRowSeq = directorRow.getAttribute("data-id");
var directorDetailDesc = directorRow.getElementsByTagName("td")[0].innerHTML;
var directorDetailGender = directorRow.getElementsByTagName("td")[1].innerHTML;
var directorDetailDateApp = directorRow.getElementsByTagName("td")[2].innerHTML;
var directorDetailDateRes = directorRow.getElementsByTagName("td")[3].innerHTML;
if (!x) {
var x = [];
var Seq = [];
var Description = [];
var Gender = [];
var DateAppointed = [];
var DateResigned = [];
}
Seq.push(directorRowSeq);
Description.push(directorDetailDesc);
Gender.push(directorDetailGender);
DateAppointed.push(directorDetailDateApp);
DateResigned.push(directorDetailDateRes);
}
else {
break;
}
}
var directorsclass = {
"directorsclass": {
"Seq": Seq,
"Description": Description,
"Gender": Gender,
"DateAppointed": DateAppointed,
"DateResigned": DateResigned
}
}
return directorsclass
};
then, when I enter my C# side, to get the details and update db, the class is only returning the first items of the array.
Is there a way of getting each object from array, pass that in to class?
c# code snippit
[HttpPost]
[Route("client/updateDirector")]
public ActionResult updateDirector([System.Web.Http.FromBody] DirectorsClass directorsclass)
{}
when it get to directorsclass, it only shows first element

Return more than one values from a function in Javascript using for loop

I am using following code snippet and I am pretty sure I am doing something that wrong that is why it is not returning more than one values. I need experts opinion on it.
function returnValues(testArray)
{
var accountId, orders, abstractOrders, titleOrder;
var childOrders = new Array();
for(var i = 0; i < testArray.length; i++)
{
accountId = typeof testArray[i] === 'undefined'?'':testArray[i].id;
orders = getOrderofParentAccount(accountId);
abstractOrders = abstractOrderYTD(orders);
titleOrder = titleOrderYTD(orders);
childOrders[abstractOrders,titleOrder];
}
return childOrders;
}
You probably want to return an array of objects:
function returnValues(testArray)
{
var accountId, orders, abstractOrders, titleOrder;
var childOrders = new Array();
for(var i = 0; i < testArray.length; i++)
{
accountId = typeof testArray[i] === 'undefined'?'':testArray[i].id;
orders = getOrderofParentAccount(accountId);
abstractOrders = abstractOrderYTD(orders);
titleOrder = titleOrderYTD(orders);
childOrders.push({abstract: abstractOrders,title: titleOrder}); //<-Changed
}
return childOrders;
}
//To retrieve the values
var orders = returnValues(yourarray);
for( var i in orders ){
console.log("====="+i+"======");
console.log('Abstract Orders:');
console.log(orders[i].abstract);
console.log('Title Orders:');
console.log(orders[i].title);
}

Calling an array item into another array

I faced the following functions (or method I don't what is right name of the ):
function getRowArray($scope, object, i){
i = i + 1;
var item = {};
var data = [];
var id = -1;
if ($scope.selectedType !== undefined) {
id = $scope.selectedType.id;
}
var rating = getRating($scope, object, id);
item['name'] = $scope.objectInfo[object]['name'];
item['objectId'] = rating.objectId;
item['hideRating'] = parseInt($scope.objectInfo[object].hideControls) & 1;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
item['ratingId'] = rating.id;
for (var i in $scope.objectInfo[object].childs) {
if ($scope.objectInfo[object].childs[i] == object){
continue;
}
data.push(getRowArray($scope, $scope.objectInfo[object].childs[i], i));
}
item['data'] = data;
return item;
}
and
function getTypeRow($scope, oobject, otype){
var item = {};
var data = [];
var rating = getRating($scope, oobject.id, otype.id);
item['name'] = otype.name;
item['objectId'] = rating.objectId;
item['typeId'] = rating.typeId;
item['ratingId'] = rating.id;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
// item['hideRating'] = parseInt($scope.objectInfo[object].hideControls);
return item;
}
I want to use the hideRating item from the first one in the second, I tried and added the commented line but I got an error it says the object is undifined, is it wrong like that or am I missing something ? thanks in advance
object is undefined because it wasn't initialized; it's not specified in the parameter list for the function getTypeRow. The oobject in the parameter list should be corrected to object:
// Correct 'oobject' to 'object'
function getTypeRow($scope, object, otype){
var item = {};
var data = [];
// Correct 'oobject' to 'object'
var rating = getRating($scope, oobject.id, otype.id);
...
}

Categories