Unable to Convert to Object - AppSync Velocity Template - velocity

My maps match the schema. I'm clearly just not understanding something. I'm a newbie to appsync, graphql, and velocity so I'm sure it's a simple mistake, but I've been going in circles for hours trying to figure out what I'm doing wrong.
Query
query MyQuery {
searchUSDAFoundationFoods(terms: "apple") {
uid
description
}
}
Response
{
"data": {
"searchUSDAFoundationFoods": null
},
"errors": [
{
"path": [
"searchUSDAFoundationFoods"
],
"data": null,
"errorType": "MappingTemplate",
"errorInfo": null,
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "Unable to convert \n[\n \n \n {\"uid\":\"usda-foundation-food-1105664\",\"description\":\"Apples, granny smith, with skin, raw\"}\n \n \n {\"uid\":\"usda-foundation-food-1105781\",\"description\":\"Apples, gala, with skin, raw\"}\n \n \n {\"uid\":\"usda-foundation-food-1105547\",\"description\":\"Apples, honeycrisp, with skin, raw\"}\n \n \n {\"uid\":\"usda-foundation-food-1105430\",\"description\":\"Apples, red delicious, with skin, raw\"}\n \n \n {\"uid\":\"usda-foundation-food-1105897\",\"description\":\"Apples, fuji, with skin, raw\"}\n] to Object."
}
]
}
Response Template
[
#foreach($entry in $context.result.hits.hits)
#set($myMap = {})
$util.qr($myMap.put("uid", $entry.get("_id")))
$util.qr($myMap.put("description", $entry.get("_source").get("description")))
$util.toJson($myMap)
#end
]
Schema
type FoodSearchResult {
uid: String
description: String
}
type Query {
searchUSDAFoundationFoods(terms: String): [FoodSearchResult]
}

It began working when I changed the response template to the following:
[
#foreach($entry in $context.result.hits.hits)
#set($myMap = {})
$util.qr($myMap.put("uid", $entry.get("_id")))
$util.qr($myMap.put("description", $entry.get("_source").get("description")))
#if( $velocityCount > 1 ) , #end
$util.toJson($myMap)
#end
]
The only change is the addition of the line:
#if( $velocityCount > 1 ) , #end
I noticed it in an example, but have found no clear explanation of what it is, how it works, or why it's needed in the velocity template programming guide on amazon's site, nor anywhere else.
Update:
The line is adding in the necessary commas to make the result valid JSON.

Related

How do I post a bulleted list using the slack api

Background
I am trying to use the slack bolt jdk along with the following dependencies:
// Slack bolt SDK
implementation("com.slack.api:bolt:1.8.1")
implementation("com.slack.api:bolt-servlet:1.8.1")
implementation("com.slack.api:bolt-jetty:1.8.1")
implementation("com.slack.api:slack-api-model-kotlin-extension:1.8.1")
implementation("com.slack.api:slack-api-client-kotlin-extension:1.8.1")
What I want to achieve (in slack)
What I currently am getting (in slack)
What I've tried so far
fun SlashCommandContext.sendSectionAndAck(
message: String,
): Response {
slack.methods(botToken).chatPostMessage { req ->
req
.channel(channelId)
.blocks {
section {
markdownText(message)
}
}
}
return ack()
}
It seems like the markdown is being formatted almost properly. The header and footer are both bold as intended, but for some reason, the bulleted list is not being formatted correctly. I have also tried replacing the * with - without any luck.
In my case, I can call the function with the following input:
val input = """
*Some header text in bold*
- item
- another item
*Some footer text also in bold*
"""
sendSectionAndAck(input)
What am I doing wrong?
The easiest workaround for this would be using '•' character itself in the text.
Slack also uses following as part of the block kit message to reflect bullet points:
"text": "• test",
"blocks": [
{
"type": "rich_text",
"block_id": "erY",
"elements": [
{
"type": "rich_text_list",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "test"
}
]
}
],
"style": "bullet",
"indent": 0
}
]
}
Another reference:
https://superuser.com/questions/1282510/how-do-i-make-a-bullet-point-in-a-slack-message
A simple jq script to prefix a stream of lines read from stdin with bullets for the purposes of pasting into a slack message:
jq -rR '"\u2022 \(.)"'

Handling multiple rows returned by IMPORTJSON script on GoogleSheets

I am trying to populate a google sheet using an API. But the API has more than one row to be returned for a single query. Following is the JSON returned by API.
# https://api.dictionaryapi.dev/api/v2/entries/en/ABANDON
[
{
"word": "abandon",
"phonetics": [
{
"text": "/əˈbændən/",
"audio": "https://lex-audio.useremarkable.com/mp3/abandon_us_1.mp3"
}
],
"meanings": [
{
"partOfSpeech": "transitive verb",
"definitions": [
{
"definition": "Cease to support or look after (someone); desert.",
"example": "her natural mother had abandoned her at an early age",
"synonyms": [
"desert",
"leave",
"leave high and dry",
"turn one's back on",
"cast aside",
"break with",
"break up with"
]
},
{
"definition": "Give up completely (a course of action, a practice, or a way of thinking)",
"example": "he had clearly abandoned all pretense of trying to succeed",
"synonyms": [
"renounce",
"relinquish",
"dispense with",
"forswear",
"disclaim",
"disown",
"disavow",
"discard",
"wash one's hands of"
]
},
{
"definition": "Allow oneself to indulge in (a desire or impulse)",
"example": "they abandoned themselves to despair",
"synonyms": [
"indulge in",
"give way to",
"give oneself up to",
"yield to",
"lose oneself in",
"lose oneself to"
]
}
]
},
{
"partOfSpeech": "noun",
"definitions": [
{
"definition": "Complete lack of inhibition or restraint.",
"example": "she sings and sways with total abandon",
"synonyms": [
"uninhibitedness",
"recklessness",
"lack of restraint",
"lack of inhibition",
"unruliness",
"wildness",
"impulsiveness",
"impetuosity",
"immoderation",
"wantonness"
]
}
]
}
]
}
]
By using the following calls via IMPORTJSON,
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/phonetics/text", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/partOfSpeech", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/definition", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/synonyms", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/example", "noHeaders")
I am able to get the following in GoogleSheets,
Whereas, the actual output according to JSON should be,
As you can see a complete row is being overwritten. How can this be fixed?
EDIT
Following is the link to sheet for viewing only.
I believe your goal as follows.
You want to achieve the bottom image in your question on Google Spreadsheet.
Unfortunately, I couldn't find the method for directly retrieving the bottom image using ImportJson. So in this answer, I would like to propose a sample script for retrieving the values you expect using Google Apps Script. I thought that creating a sample script for directly achieving your goal might be simpler rather than modifying ImportJson.
Sample script:
function SAMPLE(url) {
var res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
if (res.getResponseCode() != 200) return res.getContentText();
var obj = JSON.parse(res.getContentText());
var values = obj[0].meanings.reduce((ar, {partOfSpeech, definitions}, i) => {
definitions.forEach(({definition, example, synonyms}, j) => {
var v = [definition, Array.isArray(synonyms) ? synonyms.join(",") : synonyms, example];
var phonetics = obj[0].phonetics[i];
ar.push(j == 0 ? [(phonetics ? phonetics.text : ""), partOfSpeech, ...v] : ["", "", ...v]);
});
return ar;
}, []);
return values;
}
When you use this script, please put =SAMPLE(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2)) to a cell as the custom formula.
Result:
When above script is used, the following
Note:
In this sample script, when the structure of the JSON object is changed, it might not be able to be used. So please be careful this.
References:
Class UrlFetchApp
Custom Functions in Google Sheets

Figure out different values to send partial update to server

From a form submission I receive two objects: the original values and the dirty values. I like to figure out how to create a diff to send to the server using the following rules:
id field of the root object should always be included
all changed primitive values should be included
all nested changes should be included as well.
if a nested value other than id changed, it should include id as well.
Original values:
{
"id":10,
"name": "tkvw"
"locale": "nl",
"address":{
"id":2,
"street": "Somewhere",
"zipcode": "8965",
},
"subscriptions":[8,9,10],
"category":{
"id":6
},
}
Example expected diff objects:
1) User changes field name to "Foo"
{
"id":10,
"name":"foo"
}
2) User changes field street on address node and category
{
"id":10,
"address":{
"id": 2,
"street":"Changed"
},
"category":{
"id":5
}
}
I do understand the basics of functional programming, but I just need a hint in the right direction (some meta code maybe).
Take a look at JSON Patch (rfc6902), JSON Patch is a format for describing changes to a JSON document. For example:
[
{ "op": "replace", "path": "/baz", "value": "boo" },
{ "op": "add", "path": "/hello", "value": ["world"] },
{ "op": "remove", "path": "/foo"}
]
You generate a patch by comparing to JS objects/arrays, and then you can apply the patch to the original object (on the server side for example) to reflect changes.
You can create a patch using the fast-json-patch lib.
const obj1 = {"id":10,"name":"tkvw","locale":"nl","address":{"id":2,"street":"Somewhere","zipcode":"8965"},"subscriptions":[8,9,10],"category":{"id":6}};
const obj2 = {"id":10,"name":"cats","locale":"nl","address":{"id":2,"street":"Somewhere","zipcode":"8965"},"subscriptions":[8,9,10,11],"category":{"id":7}};
const delta = jsonpatch.compare(obj1, obj2);
console.log('delta:\n', delta);
const doc = jsonpatch.applyPatch(obj1, delta).newDocument;
console.log('patched obj1:\n', doc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-json-patch/2.0.6/fast-json-patch.min.js"></script>

Keen-io: i can't delete special event using extraction query filter

using extraction query (which used url decoded for reading):
https://api.keen.io/3.0/projects/xxx/queries/extraction?api_key=xxxx&event_collection=dispatched-orders&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800
return
{
result: [
{
mobile: "13185716746",
keen : {
timestamp: "2015-02-10T07:10:07.816Z",
created_at: "2015-02-10T07:10:08.725Z",
id: "54d9aed03bc6964a7d311f9e"
},
data : {
itemId: 2130,
num: 1
},
features: {
communityId: 2000,
dispatcherId: 39,
tradeId: 8581
}
}
]
}
but if i use the same filters in my delete query url (which used url decoded for reading):
https://api.keen.io/3.0/projects/xxxxx/events/dispatched-orders?api_key=xxxxxx&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800
return
{
properties: {
data.num: "num",
keen.created_at: "datetime",
mobile: "string",
keen.id: "string",
features.communityId: "num",
features.dispatcherId: "num",
keen.timestamp: "datetime",
features.tradeId: "num",
data.itemId: "num"
}
}
plz help me ...
It looks like you are issuing a GET request for the delete comment. If you perform a GET on a collection you get back the schema that Keen has inferred for that collection.
You'll want to issue the above as a DELETE request. Here's the cURL command to do that:
curl -X DELETE "https://api.keen.io/3.0/projects/xxxxx/events/dispatched-orders?api_key=xxxxxx&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800"
Note that you'll probably need to URL encode that JSON as you mentioned in your above post!

incorrect edge direction in infoviz's Force Directed Graph

I am trying to show force graph like "graphnode6.0-----> graphnode0.0 -------> graphnode15.0 " but when i contruct json object i always get "graphnode6.0------> graphnode0.0 <---------graphnode15.0"
My JSON object is
var json = [
{
"adjacencies": [
{
"nodeTo": "graphnode15.0",
"data": {"$type":"arrow",
"$direction":"['graphnode0.0','graphnode15.0']"}
}
],
"data": {
'$color': "#83548B",
'$type': "circle"
},
"id": "graphnode0.0",
"name": "graphnode0.0"
},
{
"adjacencies": [
{
"nodeTo": "graphnode0.0",
"data": {"$type":"arrow",
"$direction":"['graphnode6.0','graphnode0.0']"}
}],
"data": {
"$color": "#83548B",
"$type": "circle"
},
"id": "graphnode6.0",
"name": "graphnode6.0"
}
];
Am i making any mistake in this JSON structure ?
Thanks
Sumit
I had a similar problem but thanks to your quick demo, I think I've managed to fix both our issues :)
Use double quote inside your direction block.
"$direction":["graphnode1", "nodeZ"]
When I tried with single quotes
"$direction":['graphnode1', 'nodeZ']
the arrows would render in one direction only.
Hope it works for you!
You are using a string for the $direction property.
"$direction":"['graphnode6.0','graphnode0.0']"
It should be an array. Like this:
"$direction":["graphnode6.0","graphnode0.0"]
See this example code.