Google sheets API fetch the value of Merged cells - javascript

I am using Google Sheets API to display the data from my Google Spreadsheet in my javascript application. Have developed by refering this documentation. I could able to read the values from my spreadsheet but for some of the columns the cells are merged as below.
I am getting the Json response as
[
[
"Name",
"Age"
],
[
"John",
"25"
],
[
"Doe"
],
]
My expected output should be
[
[
"Name",
"Age"
],
[
"John",
"25"
],
[
"Doe",
"25"
],
]
Any help ?

To retrieve the value, you have to test if the cell is part of a merged area.
var value = (cell.isPartOfMerge() ? cell.getMergedRanges()[0].getCell(1,1) : cell).getValue();

Modify the script as following
appendPre('Name, Major:');
var lastData=''
for (i = 0; i < range.values.length; i++) {
var row = range.values[i];
if (row[4]!=''){lastData=row[4]}
// Print columns A and lastData, which correspond to indices 0 and the last known value in column E that contains merged cells.
appendPre(row[0] + ', ' + lastData);
}
so that you will recall the last value if the cell is empty

Related

Fetch data to Google Sheets

I have the API request link - http://dataservice.accuweather.com/locations/v1/countries/ASI?apikey=r0wWEqEDfOM8KwWLIIw8ADXHu2JhgyeB
I need to update the data in the google sheet with ID in one column and Country Name in another column in Google Sheets
The JSON output is for the 1st two ID is as follows
[
{
"ID": "AF",
"LocalizedName": "Afghanistan",
"EnglishName": "Afghanistan"
},
{
"ID": "AM",
"LocalizedName": "Armenia",
"EnglishName": "Armenia"
},
]
In Google Sheets rows are arrays, where each member represents a column value.
Your code should look something like this:
const sheet = SpreadsheetApp.openById('yourSpreadsheetId').getSheetByName('yourSheetName');
const data = [
{
"ID": "AF",
"LocalizedName": "Afghanistan",
"EnglishName": "Afghanistan"
},
{
"ID": "AM",
"LocalizedName": "Armenia",
"EnglishName": "Armenia"
},
]; // replace with your data fetch logic
// collect your row data into array of arrays
const rows = [];
for (const location of data) {
rows.push([location.ID, location.LocalizedName]);
}
// get range beginning at the first row and first column,
// with number of rows equels to amount of rows, and 2 as a number of cols
// and fill it with your data
sheet.getRange(1, 1, rows.length, 2).setValues(rows);
See docs for SpreadsheetApp, Spreadsheet, Sheet, Sheet.getRange(), Range.setValues()
You can achieve this with the ARRAYFORMULA. Try this in any cell in your blank Google sheet:
=arrayformula(split(trim(flatten(split(join(" ",regexreplace(transpose(IMPORTDATA("http://dataservice.accuweather.com/locations/v1/countries/ASI?apikey=r0wWEqEDfOM8KwWLIIw8ADXHu2JhgyeB")),"(\{.*ID.*\:)|(LocalizedName.*)|(EnglishName)|([""\[\]])","")),"}"))),":"))
IMPORTDATA gets your content from http://dataservice.accuweather.com/locations/v1/countries/ASI?apikey=r0wWEqEDfOM8KwWLIIw8ADXHu2JhgyeB
TRANSPOSE transposes it.
REGEXREPLACE removes a few sets of characters.
JOIN merges onto one row.
SPLIT splits into columns by }.
FLATTEN flattens the result into a column.
TRIM gets rid of leading/trailing spaces.
SPLIT splits into columns by :.
ARRAYFORMULA works down the sheet.

Fetch data from a nested array

I would like to know if there is a way to get the length from a nested array.
My data is a JSON file like this:
{
"data" :[
"item1" :'',
"item2" :[{
"id" :1,
"text":'text'
},{
"id" :2,
"text" : 'text
}]
]
}
I'm using angular 6 and ngx-restangular.
Is possible to get the item 2 length?
The main problem is the question does not provide a valid json. A valid json for the same would be like as under :
{
"data": {
"item1": "",
"item2": [{
"id": 1,
"text": "text"
},
{
"id": 2,
"text": "text"
}
]
}
}
Now you can fetch the second element size simply by
data["item2"].length
or
data.item2.length
To extend the Answer from #AurA
If you had to work with a valid array:
[
[ "item0.0", "item0.1" ],
[ "item1.0", "item1.1" ]
]
you could access the length of the nested arrays like this:
let a = [
["item0.0", "item0.1"],
["item1.0", "item1.1"]
];
let lengthA0 = a[0].length;
let lengthA1 = a[1].length;
console.log("length of a0: ", lengthA0);
console.log("length of a1: ", lengthA1);

JSON data to valid data array in JS

I need to alter my JSON API from https://demo.piwik.org/?module=API&method=VisitsSummary.getVisits&idSite=7&period=day&date=last3&format=json&token_auth=anonymous
{"2017-12-21":767,"2017-12-22":571,"2017-12-23":31}
to a valid array for my charts in NVD3.js as
[ { "key" : "Page Visits" , "values" : [ [ 1025409600000 , 767] , [ 1028088000000 , 571] , [ 1030766400000 , 31] }]
NOTE: These dates do not match the JSON and Array but highlight the conversion needed, if anyone can explain to me the date format used in NVD3.js that would be great too.
If helpful, I can add the scripts used to get data and display the NVD3 Chart.
You can use array#map to convert your object to array. Then use [ { "key" : "Page Visits" , "values" : result }]; to get the required object.
var data = {"2017-12-21":767,"2017-12-22":571,"2017-12-23":31};
var result = Object.keys(data).map(k => [new Date(k).getTime(), data[k]]);
console.log(result);

issues appending jsons to vars

So i have this json coming back from my server:
[
[
"formatted_sum_fees",
"£6.00"
],
[
"formatted_price",
"£60.00"
],
[
"formatted_sum_fees",
"£8.00"
],
[
"formatted_price",
"£120.00"
],
[
"formatted_price",
"£240.00"
],
[
"formatted_sum_fees",
"£3.20"
],
[
"formatted_sum_fees",
"£2.86"
],
[
"formatted_sum_fees",
"£2.50"
],
[
"ticket_desc",
"Later Owl Ticket"
],
[
"ticket_desc",
"Later Owl Ticket+Collector Ticket &#64 extra £4.95 per ticket"
],
[
"ticket_desc",
"Later Owl + Chance For VIP Upgrade"
],
[
"ticket_desc",
"VIP Ticket"
],
[
"ticket_desc",
"VIP Ticket + Collector Ticket &#64 extra £4.95 per ticket"
],
[
"ticket_desc",
"Skydeck Package"
],
[
"ticket_desc",
"5 Person Skydeck Table"
],
[
"ticket_desc",
"7 Person Skydeck Table"
],
[
"ticket_desc",
"10 Person Skydeck Table"
]
]
Now what im wanting is my ajax call to put these into a table. The first fees and price goes with the first ticket_desc. Each and everytime! The code i have the append to table code. ITs getting the price, fees and description into vars. How do i go about doing this?
This is how i was attempting to do this
success: function(json) {
for (var i = 0; i < json.length; i++) {
var section = json[i][0];
if (section == "ticket_desc") {
var ticket = json[i][1];
debugger;
}
However i ran into issues where the ticket_desc isn't matching up, However i didnt think it would work!
Thanks
Sam
It's not exactly clear to me what the eventual data format is supposed to be, and there are probably many different ways of processing your json, but let's try:
I'd prefer an array of objects that have a description and fee property. For example:
var ticket = {
description: "Later Owl Ticket",
fee: "£6.00"
};
Now, if I understand your data correctly, the order of the array in the json determines the matches between fees and descriptions.
If this is the case, and you can be certain there are no missing values, a straightforward solution could be:
var nrOfTickets = json.length / 2;
var fees = json.slice(0, nrOfTickets); // First half
var descriptions = json.slice(nrOfTickets); // Second half
var tickets = descriptions.map(function(descrArr, index) {
var feeArr = fees[index];
return {
description: descrArr[1],
fee: feeArr[1]
};
});
If you want to make it shorter, you could do:
var tickets = [];
for (var i = 0, l = json.length / 2; i < l; i += 1) {
tickets.push({
fee: json[i][1],
description: json[i+l][1]
});
};
If the fees and descriptions are scrambled, you can sort them like so:
var descriptions = [],
fees = [];
json.forEach(function(arr) {
if (arr[1] === "ticket_desc") {
descriptions.push(arr);
} else {
fees.push(arr)
};
});

Is it possible to store integers as keys in a javascript object?

I'm creating an index file in JSON, which I'm using as a sort-of-database index for a javascript application I'm working on.
My index will look like this:
{
"_id": "acomplex_indices.json",
"indexAB": {
"title": {
"Shawshank Redemption": [
"0"
],
"Godfather": [
"1"
],
"Godfather 2": [
"2"
],
"Pulp Fiction": [
"3"
],
"The Good, The Bad and The Ugly": [
"4"
],
"12 Angry Men": [
"5"
],
"The Dark Knight": [
"6"
],
"Schindlers List": [
"7"
],
"Lord of the Rings - Return of the King": [
"8"
],
"Fight Club": [
"9"
],
"Star Wars Episode V": [
"10"
],
"Lord Of the Rings - Fellowship of the Ring": [
"11"
],
"One flew over the Cuckoo's Nest": [
"12"
],
"Inception": [
"13"
],
"Godfellas": [
"14"
]
},
"year": {
"1994": [
"0",
"3"
],
"1972": [
"1"
],
"1974": [
"2"
],
"1966": [
"4"
],
"1957": [
"5"
],
"2008": [
"6"
],
"1993": [
"7"
],
"2003": [
"8"
],
"1999": [
"9"
],
"1980": [
"10"
],
"2001": [
"11"
],
"1975": [
"12"
],
"2010": [
"13"
],
"1990": [
"14"
]
}
}
}
So for every keyword (like Pulp Fiction), I'm storing the matching document-id(s).
My problem is with integers/numbers/non-string data, like the release year in the above example. This is stored as a string, while I had hoped it would be stored as a number.
I'm creating the index entries like this:
// indices = the current index file
// doc = the document to update the index with
// priv.indices = all indices defined for this application instance
// priv.indices.fields = index fields e.g. "year", "director", "title"
// priv.indices.name = name of this index
priv.updateIndices = function (indices, doc) {
var i, j, index, value, label, key, l = priv.indices.length;
// loop all indices to add document
for (i = 0; i < l; i += 1) {
index = {};
index.reference = priv.indices[i];
index.reference_size = index.reference.fields.length;
index.current = indices[index.reference.name];
for (j = 0; j < index.reference_size; j += 1) {
label = index.reference.fields[j]; // like "year"
value = doc[label]; // like 1985
// if document has a label field (e.g. doc.year = 1985)
if (value !== undefined) {
// check if the index file already contains an entry for 1985
index.current_size = priv.getObjectSize(index.current[label]);
if (index.current_size > 0) {
// check if the document id is already in the index
// in case the data is updated (e.g. change 1982 to 1985)
key = priv.searchIndexByValue(
index.current[label],
doc._id,
"key"
);
if (!!key) {
delete index.current[label][key];
}
}
// create a new array if 1985 is not in the index yet
if (index.current[label][value] === undefined) {
index.current[label][value] = [];
}
// add the document id to an existing entry
index.current[label][value].push(doc._id);
}
}
}
return indices;
};
This works fine, except that fields I want to store as non-strings (integers, numbers or datetime), like the year in the above example end up as strings in my index.
Question:
Is it at all possible to store "non-string" types in a JSON document? If so, can I also store the key of a key/value pair as a "non-string" element.
If not, would I have to add a parameter to my index definitions declaring the type of each key in order to modify the key-string when I run into it or is there a better way to do it?
Thanks!
Is it at all possible to store "non-string" types in a JSON document?
Yes. The value of a property can be a string, number, boolean, object, array or null (undefined is a notable exception - it's a native JavaScript type but it's not a valid JSON value).
Can I also store the key of a key/value pair as a "non-string" element?
No. The key name must always be a string. However, that doesn't mean you can't parse that string into some other JavaScript type. For example, if you have a string but need a number, you can use the parseInt function, or the unary + operator.
See the JSON grammar for more detail.
no you can't, in JSON keys are strings.
the best you can do is storing string representations of those keys, wether integer or objects(more complicated, you have to build a serialization function).
If you want to use only consecutive integers keys starting from 0, then you can use arrays.
According to the json spec, you can have a number anywhere you could have a value. So the key of an object must be a string, but the value can be a number. Also any of the values in an array can be a number.
The spec is beside the point though; I believe the issue is this line:
index.current[label][value].push(doc._id);
When you read doc._id, that is a string. If you want to store it in the JSON as a number, you need to cast it:
index.current[label][value].push(parseInt(doc._id, 10));
Also note that having just numbers as IDs is not valid HTML.

Categories

Resources