Java Google Sheets API example with autoResizeDimensionsRequest - google-sheets-api

I'm wondering how to use autoResizeDimensions in order to set the columns to auto resize. The following
List<Request> requests = new ArrayList<>();
AutoResizeDimensionsRequest autoResizeDimensions = new AutoResizeDimensionsRequest();
requests.add(new Request()
.setAutoResizeDimensions(autoResizeDimensions));
BatchUpdateSpreadsheetRequest batchUpdateRequest = new BatchUpdateSpreadsheetRequest()
.setRequests(requests);
SHEETS.spreadsheets().batchUpdate(spreadsheetId, batchUpdateRequest)
.execute();
returns the following error message
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid requests[1].autoResizeDimensions: Only the COLUMNS dimension is supported",
"reason" : "badRequest"
} ],
"message" : "Invalid requests[1].autoResizeDimensions: Only the COLUMNS dimension is supported",
"status" : "INVALID_ARGUMENT"
I'm also interested in setting a specific width for a column. I haven't found any examples using java. If anyone has come across one or know how would love to no about it.
Additionally I've added setDimensions to that code
DimensionRange dimensions = new DimensionRange().setDimension("A1:C6");
with the setAutoResizeDimensions
requests.add(new Request()
.setAutoResizeDimensions(autoResizeDimensions
.setDimensions(dimensions)));
But I'm getting the following error
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid value at 'requests[3].auto_resize_dimensions.dimensions.dimension' (TYPE_ENUM), \"A1:C6\"",
"reason" : "badRequest"
} ],
"message" : "Invalid value at 'requests[3].auto_resize_dimensions.dimensions.dimension' (TYPE_ENUM), \"A1:C6\"",
"status" : "INVALID_ARGUMENT"
Thanks
Conteh

The failures all stem from the same reason: AutoResizeDimensionRequest is not setup properly.
You need to supply a valid DimensionRange into the request's dimensions field in order for the request to know which dimensions to resize. The documentation for DimensionRange describes it's purpose: A range along a single dimension on a sheet. All indexes are zero-based. Indexes are half open: the start index is inclusive and the end index is exclusive. Missing indexes indicate the range is unbounded on that side.
The first error ("Invalid requests[1].autoResizeDimensions: Only the COLUMNS dimension is supported") is because the request is using the default DimensionRange, which means the DimensionRange.dimension field is using its default value of DIMENSION_UNSPECIFIED. The field is an enum of type Dimension whose default value is DIMENSION_UNSPECIFIED. So the error message is saying, "Only COLUMNS is supported" and is implicitly saying, "... but you supplied DIMENSION_UNSPECIFIED or ROWS".
The second error ("Invalid value at 'requests[3].auto_resize_dimensions.dimensions.dimension' (TYPE_ENUM), \"A1:C6\"") is because you wrote an A1 range into the dimension field. The error message is saying: "You gave me an invalid value. I am an enum, but you gave me A1:C6, and that isn't a valid enum."
The valid values for dimension are ROWS or COLUMNS (and AutoResizeDimensionRequest requires that you specify COLUMNS). In addition, you'll want to specify the sheetId (the ID of the sheet whose columns you want to resize) and a startIndex and endIndex of which columns you want to resize.
For example, if you wanted to automatically resize rows 0 and 1, you would use:
AutoResizeDimensionsRequest autoResizeDimensions = new AutoResizeDimensionsRequest();
DimensionRange dimensions = new DimensionRange().setDimension("COLUMNS").setStartIndex(0).setEndIndex(2);
autoResizeDimensions.setDimensions(dimensions);
(endIndex is 2 because end indexes are exclusive, whereas start indexes are inclusive.)

Related

Which is the proper response code for this scenario - 207 vs 400 status code

I am designing the API where all the following three cases are possible
All the inputs in the array are correct, so this API will return the 200 status code
Sample output: 200 Status code
[{ "status" : "success", "value" : "some response" }, { "status" : "success", "value" : "some response" }]
Few inputs in the array are correct, so this API will return the 207 Multi-Status code
Sample output: 207 Multi-Status code
[{ "status" : "success", "value" : "some response" }, { "status" : "fail", "value" : "reason for failure" }, { "status" : "success", "value" : "some response" }]
All the inputs are wrong in the array. In this case do I need to send the 400 Bad Request (OR) 207 status code ?
Because if I send the 400 Bad Request then the response format will not be consistent like below
Sample Output: 400 Status code
{"errorcode" : "XXXXXX", "message" : "It is failed due to invalid inputs. Input must contain XXXX"}
In Case 3, do I need to send the 400 status code response or 207 status code response with all the status as 'FAIL'. Which is correct and consistent?
There is a huge difference between 2xx and 4xx codes.
2xx like 207 means the request is valid and returns values (success or fails).
However 4xx codes like 400 means that client sent an invalid request.
For instance if you have to provide at least one input in the array and client request with an empty array, it's a bad request.
In your case, the request looks valid and you have a mixed behavior of 2xx and 4xx.
If client is able to use part of your results then it's a 207, if he can use successes without failures then the result is 2xx.
If he can't and he needs each input to be valid then it's a 4xx as the request should contains only valid inputs (resulting in success only).
For instance in case 3, a 400 makes sense as user can't continue his process with failures only.
You should be able to format this error by adding a property "details" containing your array of input's failures like
400
{
"errorcode" : "XXXXXX",
"message" : "Only invalid inputs. Input must contain XXXX",
"details" : [{
"status" : "fail",
"value" : "reason for failure"
}, {
"status" : "fail",
"value" : "reason for failure"
}, {
"status" : "fail",
"value" : "reason for failure"
}]
}

ElasticSearch Query results in error "input_mismatch_exception" when executing LOWER()

I am working on search functionality and I need to execute a simple query that checks if there is anything matching the search string converted to lowercase. In simpler terms, user searches "SiteName", and I query if there is anything matching "sitename".
However, I get an error when I use LOWER() function in the query.
This is what I tried:
POST /_sql?format=json
{
"query":"SELECT siteid, sitename FROM zones WHERE
sitename LIKE LOWER('SiteFirst') ", "fetch_size" : 90
}
and I get this error:
{
"error" : {
"root_cause" : [
{
"type" : "parsing_exception",
"reason" : "line 1:70: mismatched input 'LOWER' expecting {'?',
STRING}"
}
],
"type" : "parsing_exception",
"reason" : "line 1:70: mismatched input 'LOWER' expecting {'?', STRING}",
"caused_by" : {
"type" : "input_mismatch_exception",
"reason" : null
}
},
"status" : 400
}
This same query works without LOWER().
Any suggestions about how to fix this error?
Thanks!
I'm pretty sure the LOWER is called LCASE in ES SQL.
More importantly, LIKE works only on exact fields, plus it's recommended to use MATCH instead of LIKE.
So try this:
POST /_sql?format=json
{
"query": "SELECT siteid, sitename FROM zones WHERE MATCH(sitename, 'SiteFirst')",
"fetch_size": 90
}

Collapsing a group using Google Sheets API

So as a workaround to difficulties creating a new sheet with groups I am trying to create and collapse these groups in a separate call to batchUpdate. I can call request an addDimensionGroup successfully, but when I request updateDimensionGroup to collapse the group I just created, either in the same API call or in a separate one, I get this error:
{
"error": {
"code": 400,
"message": "Invalid requests[1].updateDimensionGroup: dimensionGroup.depth must be \u003e 0",
"status": "INVALID_ARGUMENT"
}
}
But I'm passing depth as 0 as seen by the following JSON which I send in my request:
{
"requests":[{
"addDimensionGroup":{
"range":{
"dimension":"ROWS",
"sheetId":0,
"startIndex":2,
"endIndex":5}
}
},{
"updateDimensionGroup":{
"dimensionGroup":{
"range": {
"dimension":"ROWS",
"sheetId":0,
"startIndex":2,
"endIndex":5
},
"depth":0,
"collapsed":true
},
"fields":"*"
}
}],
"includeSpreadsheetInResponse":true}',
...
I'm not entirely sure what I am supposed to provide for "fields", the documentation for UpdateDimensionGroupRequest says it is supposed to be a string ("string ( FieldMask format)"), but the FieldMask definition itself shows the possibility of multiple paths, and doesn't tell me how they are supposed to be separated in a single string.
What am I doing wrong here?
The error message is actually instructing you that the dimensionGroup.depth value must be > 0:
If you call spreadsheets.get() on your sheet, and request only the DimensionGroup data, you'll note that your created group is actually at depth 1:
GET https://sheets.googleapis.com/v4/spreadsheets/{SSID}?fields=sheets(rowGroups)&key={API_KEY}
This makes sense, since the depth is (per API spec):
depth numberThe depth of the group, representing how many groups have a range that wholly contains the range of this group.
Note that any given particular DimensionGroup "wholly contains its own range" by definition.
If your goal is to change the status of the DimensionGroup, then you need to set its collapsed property:
{
"requests":
[
{
"updateDimensionGroup":
{
"dimensionGroup":
{
"range":
{
"sheetId": <your sheet id>,
"dimension": "ROWS",
"startIndex": 2,
"endIndex": 5
},
"collapsed": true,
"depth": 1
},
"fields": "collapsed"
}
}
]
}
For this particular Request, the only attribute you can set is collapsed - the other properties are used to identify the desired DimensionGroup to manipulate. Thus, specifying fields: "*" is equivalent to fields: "collapsed". This is not true for the majority of requests, so specifying fields: "*" and then omitting a non-required request parameter is interpreted as "Delete that missing parameter from the server's representation".
To change a DimensionGroup's depth, you must add or remove other DimensionGroups that encompass it.

How to check if a key element exists and if present update it?

I am using mule community edition. So no Dataweave. I am consuming a rest service in my application. In the json response from this backend rest service. I need to check if a particular element exists inside muliple multiple elements of an array and wherever it exists I need to update its value.
E.g. (sample)
Input Request : [ { "id" : "1", "item" : "car", "make" : "Tonda" }, { "id" : "1", "item" : "car" } ]
using foreach to iterate array . Inside for each need to do something like below in expression component.
if( payload.make exists) { payload.make = "Tero"; }
But I do not know , how to check "if element exists"" condition. I tried below in expression component
if( payload.make != empty) { payload.make = "Tero"; }
But it did not work and gives error "Execution of the expression failed (org.mule.api.expression.ExpressionRuntimeException)"" for each array element wherever the particular key(make) is not present
inside foreach use the expression: #[payload.containsKey('make')] to check if the json key make exists or not. This will return true or false
Easy and simple!
Ref: https://forums.mulesoft.com/questions/71478/how-to-check-if-a-key-element-exists-and-if-presen.html?childToView=71502#answer-71502
Tested in a flow, if your payload is a single object and not a collection you can do MEL:
#[(payload.?make != empty) ? "EXISTS" : " OPS NO"]
Just change "EXISTS" with your true condition and "OPS NO" with the false one.
According to documentation: https://docs.mulesoft.com/mule-user-guide/v/3.7/mule-expression-language-reference
Null Safety
To access properties in a null safe manner, add the .? operator before one or more objects in a chain. In the following expression, if fieldA is null, the expression evaluates to null instead of a NullPointerException.

Possible to use angular-datatables with serverside array sourced data instead of object sourced data

I'm trying to use angular-datatables with serverside processing. However, it seems that angular-datatables expects that the data from the server is in object format (object vs array data described) with column names preceding each table datapoint. I'd like to configure angular-datatables to accept array based data since I can't modify my server side output which only outputs data in array format.
I'm configuring Datatables in my javascript like so:
var vm = this;
vm.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
url: 'output/ss_results/' + $routeParams.uuid,
type: 'GET'
})
.withDataProp('data')
.withOption('processing', true)
.withOption('serverSide', true);
My data from the server looks like this in array format:
var data = [
[
"Tiger Nixon",
"System Architect",
"$3,120"
],
[
"Garrett Winters",
"Director",
"$5,300"
]
]
But as far as I can tell, angular-datatables is expecting the data in object format like so:
[
{
"name": "Tiger Nixon",
"position": "System Architect",
"extn": "5421"
},
{
"name": "Garrett Winters",
"position": "Director",
"extn": "8422"
}
]
I tried not defining dtColumns or setting it to an empty array like vm.dtColumns = []; but I get an error message when I do that. When I configure dtColumns with a promise to load the column data via ajax I get datatables error #4 because it can't find the column name preceding my table datapoints in the data retrieved from the server.
Is it possible to configure angular-datatables to accept array based data? I can't find anything on the angular-datatables website that indicates it can be configured this way.
Edit: So I removed the .withDataProp('data') which I think was causing the problem. The table works a little better now but it's still broken. After it loads, I get the message No matching records found. Even though right below it it says Showing 1 to 10 of 60,349 entries
Previous1…456…6035Next Does anyone know why this might be?
If you want to use an array of arrays instead of an array of objects, simply refer to the array indexes instead of the object names :
$scope.dtColumns = [
DTColumnBuilder.newColumn(0).withTitle('Name'),
DTColumnBuilder.newColumn(1).withTitle('Position'),
DTColumnBuilder.newColumn(2).withTitle('Office'),
DTColumnBuilder.newColumn(3).withTitle('Start date'),
DTColumnBuilder.newColumn(4).withTitle('Salary')
]
demo using the famous "Tiger Nixon" array loaded via AJAX -> http://plnkr.co/edit/16UoRqF5hvg2YpvAP8J3?p=preview