I'm using Google Scripts to maintain a list of Chrome devices on our domain.
I'm using the AdminDirectory.Chromeosdevices.list method to get all the information I require and write it to a sheet.
I am then trying to write a script to write information to the annotatedLocation and annotatedAssetId fields using the Chromeosdevices.update method.
My problem: I receive a phrase error using the following, from looking at the suggestion: update(resource, customerId, deviceId, optionalArgs) I don't seem to have a 'resource', I cannot seem to find any way to get this value.
Any suggestions as to how I can get the resource??
var options = {
"annotatedAssetId": (data[i][13] == "") ? data[i][3] : data[i][13],
"annotatedLocation": (data[i][14] == "") ? data[i][4] : data[i][14],
"notes": (data[i][15] == "") ? data[i][7] : data[i][15],
"orgUnitPath": (data[i][16] == "") ? data[i][15] : data[i][16]
}
var device = AdminDirectory.Chromeosdevices.update(data[i][11],"my_customer", data[i][10], options)
Thank you
I think you're referring to this line:
In the request body, supply a Chromeosdevices resource with the
following properties:
resource is referring to Chromeosdevices resource.
{
"kind": "admin#directory#chromeosdevice",
"etag": etag,
"deviceId": string,
"serialNumber": string,
"status": string,
"lastSync": datetime,
"supportEndDate": datetime,
"annotatedUser": string,
"annotatedLocation": string,
"annotatedAssetId": string,
"notes": string,
"model": string,
"meid": string,
"orderNumber": string,
"willAutoRenew": boolean,
"osVersion": string,
"platformVersion": string,
"firmwareVersion": string,
"macAddress": string,
"bootMode": string,
"lastEnrollmentTime": datetime,
"orgUnitPath": string,
"recentUsers": [
{
"type": string,
"email": string
}
],
"ethernetMacAddress": string,
"activeTimeRanges": [
{
"date": date,
"activeTime": integer
}
]
}
Click the link for more info.
This is working for me. Hopefully it helps you out.
function getDeviceID(assetID) {
//Find chrome device
var assetTag = 'asset_id:' + assetID;
var chromebookDevices = (AdminDirectory.Chromeosdevices.list("my_customer", {
query: assetTag
}));
//Change values
chromebookDevices.chromeosdevices[0].annotatedUser = 'New name';
//Push changes
var updatedChromebook =(AdminDirectory.Chromeosdevices.update(chromebookDevices.chromeosdevices[0], "my_customer", chromebookDevices.chromeosdevices[0].deviceId));
}
Maybe this has been figured out already, but the first argument is the JSON object noogui refers to. Use the method on adminDirectory.Chromeosdevices.get() to first retrieve the object. Modify this object as needed, then use adminDirectory.Chromeosdevices.update() with that modified object as the first argument.
Related
I am attempting to parse JSON in Office Scripts that prints the headings and row information on the sheet. I'm successfully fetching the data, but I keep getting the error message that my information is not iterable on the "for" line.
async function main(workbook: ExcelScript.Workbook) {
// Call the API
const response = await fetch('WEBADDRESSHERE');
const sitedata: siteInformation[] = await response.json();
// Set the types for rows
const rows: (string | number)[][]=[];
// Iterate through the data and get the row headings
for (let site of sitedata){
rows.push([site.SiteID, site.SiteDescription, site.EffectiveDate, site.DataPresent]);
}
// Get the current sheet
const sheet = workbook.getActiveWorksheet();
// Set the range to start writing the details
const range = sheet.getRange('A2').getResizedRange(rows.length - 1, rows[0].length - 1);
range.setValues(rows);
return;
}
interface siteInformation {
SiteID: string;
SiteDescription: string;
EffectiveDate: date;
DataPresent: string;
}
This is the sample JSON I'm working with.
{
"1": {
"SiteID": "2",
"SiteDescription": "SiteA",
"EffectiveDate": "2022-08-01",
"DataPresent": "Yes"
},
"2": {
"SiteID": "2",
"SiteDescription": "SiteA",
"EffectiveDate": "2022-08-02",
"DataPresent": "Yes"
}
}
There are a few things going on here
I believe the reason you're getting the "not iterable" error is because you're using the wrong loop. To loop through a JSON dictionary, you need to use for...in... not for...of...
Second, when you update the loop, you'll get the key back as the element. So you need to use the key with the sitedata to get the specific JSON element you're trying to loop through.
Lastly, although it's not necessary, you listed the date type as a type in the interface. This is showing an error on the office scripts IDE for me. So you may want to update that to string.
You can see a code snippet with the updates below:
async function main(workbook: ExcelScript.Workbook) {
// Call the API
const sitedataStr = `{
"1": {
"SiteID": "1",
"SiteDescription": "SiteA",
"EffectiveDate": "2022-08-01",
"DataPresent": "Yes"
},
"2": {
"SiteID": "2",
"SiteDescription": "SiteA",
"EffectiveDate": "2022-08-02",
"DataPresent": "Yes"
}
}`
let sitedata: siteInformation = JSON.parse(sitedataStr)
// Set the types for rows
const rows: (string | number)[][] = [];
// Iterate through the data and get the row headings
for (let key in sitedata) {
let site:siteInformation = sitedata[key]
rows.push([site.SiteID, site.SiteDescription, site.EffectiveDate, site.DataPresent]);
}
}
interface siteInformation {
SiteID: string;
SiteDescription: string;
EffectiveDate: string;
DataPresent: string;
}
I'm creating API server with Ktor and using exposed SQL.
I have two tables like below:
/// Performance Table
#kotlinx.serialization.Serializable
data class PerformanceDAO(val performanceId: String, val title: String, val actor: String)
object Performances : Table() {
val performanceId: Column<String> = varchar("performanceId", 20)
val title: Column<String> = varchar("title", 50)
override val primaryKey = PrimaryKey(performanceId)
}
//Actor Table
object Actors: Table() {
val performanceId: Column<String> = reference("performanceId", Performances.performanceId)
val name: Column<String> = varchar("name", 10)
}
and I'm trying to get data this way:
class PerformanceDAOImpl : PerformanceDAOFacade {
private fun resultRowToPerformance(row: ResultRow) = PerformanceDAO(
performanceId = row[Performances.performanceId],
title = row[Performances.title],
actor = row[Actors.name],
)
override suspend fun allPerformances(): List<PerformanceDAO> = dbQuery {
Actors.leftJoin(Performances)
.slice(Actors.name, Performances.title, Performances.performanceId)
.selectAll()
.groupBy(Performances.title).map(::resultRowToPerformance)
}
}
and then I got only one actors without a key.
{
"performanceId": "PF13234",
"title": "Harry footer",
"actor": [
"John"
]
},
but I want get data like this
{
"performanceId": "PF13234",
"title": "Harry footer",
"actor": [
{
"name: "John",
"image": "/upload/images/image.jpg"
},
{
"name: "Harry",
"image": "/upload/images/image.jpg"
},
]
},
I want to know how to make sub object in JSON with Exposed SQL!
You have to create a separate data class ActorDTO and map it in your code by making subquery. Also, I would advice to make Exposed Entities and then map them to your DAO, it can be much simpler but will add some boilerplate code.
Please check documentation
Below is the json response
{
"details": [
{
"UserName": "john",
"id": "abc_123",
"LastName": "smith"
}
]
}
I need to delete only the UserName parameter :
request.delete("http://localhost:8080/details/id/UserName");
The above code does not seem to work and my expected is as below
{
"details": [
{
"id": "abc_123",
"LastName": "smith"
}
]
}
Please check for the Minimal, Complete, and Verifiable example before posting a question on SO, There are people to help but we would need to know what you've tried beforehand.
To answer your question, You should use a PUT and not a DELETE cause you are trying to update the payload. DELETE as the name suggests will delete the complete resource
Check this link for more detail
PUT calls are resource specific so you will have to mention which entity should be affected.
I have come up with a sample code based on the details you've provided
Used HashMap here but you could also post the body as such or use POJO or JSONObject
{
Map < String, Object > map = new HashMap < > ();
map.put("details", Arrays.asList(new HashMap < String, Object > () {
{
put("id", "abc_123");
put("LastName", "smith");
}
}));
RequestSpecification req = RestAssured.given();
req.header("Content-Type", "application/json");
req.body(map).when();
Response resp = req.put("http://localhost:8080/details/id/abc_123");
String body = resp.asString();
System.out.println("Response is : " + body);
}
Is it possible to serialize optional values in F# using FsPickler such that:
when the value is Some(), the value contained is serialized
and when it is None, it does not get serialized at all?
With the following example code:
type Person = { name: string; age: int option }
let data = [
{ name = "Helena"; age = Some(24) };
{ name = "Peter"; age = None }
]
let jsonSerializer = FsPickler.CreateJsonSerializer(true, true)
let streamWriter = new StreamWriter(#"C:\output.json")
let out = jsonSerializer.SerializeSequence(streamWriter, data)
the output.json file contains the following JSON:
[
{
"name": "Helena",
"age": {
"Some": 24
}
},
{
"name": "Peter",
"age": null
}
]
But I would like the contents of JSON file to look like this instead:
[
{
"name": "Helena",
"age": 24
},
{
"name": "Peter"
}
]
I am using FsPickler.Json v3.2.0 and Newtonsoft.Json v9.0.1.
UPDATE (January 11, 2017): Using the script in the gist linked by Stuart in the answer below, I got it working like this:
let obj = { name = "Peter"; age = None }
let stringWriter = new StringWriter()
let jsonSerializer = new JsonSerializer()
jsonSerializer.Converters.Add(new IdiomaticDuConverter())
jsonSerializer.NullValueHandling <- NullValueHandling.Ignore
jsonSerializer.Serialize(stringWriter, obj)
Using Newtonsoft.Json you can use the gist here (credit: Isaac Abraham) to give you the behaviour you are after.
It's funny, just moments before you posted this, I was looking to see if the same thing exists within FsPickler.Json, but came to no conclusions. You could use TypeShape which is used in FsPickler to make the gist cleaner, but not sure if FsPickler.Json can do this for you out of the box.
I'm the author FsPickler, so thought I'd repost a response I gave in a similar issue.
No, managing the shape of the serialization formats is beyond the design goals of this library. While you could use pickler combinators to influence how serialized types look like, this will only take you so far.
With FSharp.Json library it would work just well:
open FSharp.Json
type Person = { name: string; age: int option }
let data = [
{ name = "Helena"; age = Some(24) };
{ name = "Peter"; age = None }
]
let json = Json.serialize data
This produces following JSON:
[
{ "name": "Helena", "age": 24 },
{ "name": "Peter", "age": null }
]
How option None is serialized is configurable. Here's how to omit the option member that has None value, pay attention to config:
let config = JsonConfig.create(serializeNone=SerializeNone.Omit)
let json = Json.serializeEx config data
Disclosure: I'm author of FSharp.Json library.
I'd like to create a JSON object in Swifty that has the form:
{
"store": {
"id": {
"test": "test"
},
"type": "retail",
"name": "store1"
}
}
Is there a way to combine types in a Dictionary to use with Swifty (String and JSON)? Quotes works, but when I try to assign a variable, it complains: Cannot assign value of type 'String' to type 'JSON?':
func jsonTest()->String {
var storeJson = [String: JSON]()
var someJson = JSON(["test":"test"])
storeJson["id"] = someJson
storeJson["type"] = "retail" // <-- works fine
var name = "store1"
storeJson["name"] = name // <-- Doesn't work
var store = JSON(storeJson)
return store.rawString()!
}
The reason
storeJson["type"] = "retail"
works differently than
storeJson["name"] = name
is because the first one follows a different path in the code. Specifically, it uses the init(stringLiteral value: StringLiteralType) method in the following extension (source).
extension JSON: Swift.StringLiteralConvertible {
public init(stringLiteral value: StringLiteralType) {
self.init(value)
}
public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
self.init(value)
}
public init(unicodeScalarLiteral value: StringLiteralType) {
self.init(value)
}
}
I'll explain further after we talk about how to fix your specific problem.
Possible solution #1:
storeJson["name"]?.string = name
Output:
{
"id" : {
"test" : "test"
},
"type" : "retail"
}
The reason
storeJson["name"]?.string = name
doesn't work as we might think is because of the optional chaining. Right now, if we ran this through the debugger, we wouldn't see anything meaningful. In fact, we would see nothing. This is a bit concerning and likely means storeJson["name"] is nil, so the statement is not executing any further. Let's verify our hypothesis by making it blow up. We'll change the line to:
storeJson["name"]!.string = name
In this case, with your current code, you'll likely get
fatal error: unexpectedly found nil while unwrapping an Optional value
as you should because storeJson["name"] is in fact nil. Therefore, this solution doesn't work.
Possible solution #2:
As you correctly noted in your answer, if you add a storeJson["name"] = JSON(name), you'll get the desired behavior:
func jsonTest()->String {
var storeJson = [String: JSON]()
var someJson = JSON(["test":"test"])
storeJson["id"] = someJson
storeJson["type"] = "retail" // <-- works fine
var name = "store1"
storeJson["name"] = JSON(name) // <-- works!
var store = JSON(storeJson)
return store.rawString()!
}
Output:
{
"id" : {
"test" : "test"
},
"name" : "store1",
"type" : "retail"
}
Great! Therefore, this solution works! Now, later in your code you can alter it however you want using .string and the like.
Explanation
Back to why the string literal works. You'll notice in the init, it has
self.init(value)
which passes through the objects init, which then goes through the case statement
...
case let string as String:
_type = .String
self.rawString = string
...
When you call storeJson["name"] = JSON(name), you're skipping the StringLiteralType init and simply going into the switch.
Therefore, you could interchange
storeJson["type"] = "retail"
with
storeJson["type"] = JSON("retail")
It turns out it works to change:
storeJson["name"] = name
to
storeJson["name"] = JSON(name)