dust js: aliasing an object not working - dust.js

Template
{#person alias=root}{alias.value}: {name}, {age}{/person}
data:
{
"root": {value:"MR."},
"person": {
"name": "Larry",
"age": 45
}
}
Expected output:
MR. Larry, 45
Actual output:
: Larry, 45
I'm trying to alias an object like shown above. But its not working. Please have a look into this fiddle http://jsfiddle.net/G86mu/1/.
If i replace {value:"MR."} with a string say "root":"Mr." and change my template to
{#person alias=root}{alias}: {name}, {age}{/person}
the output is as expected. Please let me know how do i alias an object

The reason this isn't working is because the context within Dust is not the same as the JSON you pass in to dust.render. Internally, Dust wraps your JSON so that it can include params, globals, and blocks in the context.
So, you are not adding alias to the current context, as you might assume. Instead, you are adding alias one level above your current context. Although the representation isn't exactly accurate, it should be helpful for explanation purposes:
// Incorrect:
{
"root": {
"value": "MR."
},
"person": {
// Current context
"alias": {
"value": "MR."
},
"name": "Larry",
"age": "45"
}
}
// (more) correct:
{
"root": {
"value": "MR."
},
"alias": {
"value": "MR."
"person": {
// Current context
"name": "Larry",
"age": "45"
}
}
}
When the context is viewed in this way, it makes sense why {#person alias=root}{alias.value}: {name}, {age}{/person} will not work. When using the dot-notation inside of a reference (as in {alias.value}, dust starts in the current context and goes down. Since there is no "alias" object inside of the current context, dust gives up, and you get an empty string.
However, if when you don't use the dot-notation, dust starts at the current context and searches up. The first time it finds a match, it will use that match. So, for your example, you could use the following to get your expected output.
{#person alias=root}{#alias}{value}{/alias}: {name}, {age}{/person}
Alternatively, if you could use:
{#person aliasVal=root.value}{aliasVal}: {name}, {age}{/person}

Related

How to indicate that the response body is a List in Swagger UI docs using FastAPI?

I describe the structure of the outgoing JSON in the model class, however I cannot make the output as a list.
My model class:
class versions_info(BaseModel):
""" List of versions """
version : str = Field(..., title="Version",example="2.1.1")
url : str = Field(..., title="Url",example="https://ocpi.wedwe.ww/ocpi/2.1.1/")
And in the documentation I see:
However, I need it to be displayed as:
[
{
"version": "2.1.1",
"url": "https://www.server.com/ocpi/2.1.1/"
},
{
"version": "2.2",
"url": "https://www.server.com/ocpi/2.2/"
}
]
What am I doing wrong?
You can indicate that you're returning a List by wrapping the response_model you've defined in List[<model>].
So in your case it'd be:
#app.get('/foo', response_model=List[versions_info])

Mapbox GL JS: How can I use JavaScript with expressions to change layer layout?

I'm using Overpass to fetch OSM data and in Mapbox show the closest point of interest of a couple of 'categories'. I convert the OSM data to a GeoJSON layer and add it to Mapbox as a symbol layer with a marker image on each point in the data. The result looks like this:
I want to change the text displayed beneath each marker to something other than the variables I use to categorize the data. My first idea was to use a JS object like:
translate = {
'water': 'Waterway',
'city': 'City Center',
'school': 'Elementary School',
..etc
}
and then run each name through translate[venue_type]. This doesn't seem to work that easily though.
The marker is added as a layer like this:
map.loadImage(
'./img/map_marker3.png',
(error, image) => {
if (error) throw error;
if (!map.hasImage('custom-marker')) {
map.addImage('custom-marker', image);
}
map.addSource('venues',
{
'type': 'geojson',
'data': data
});
map.addLayer({
"id": "venues",
"type": "symbol",
"source": "venues",
'layout': {
'visibility': 'none',
'icon-image': 'custom-marker',
'icon-size': 1,
'icon-anchor': 'bottom',
'icon-allow-overlap': true,
// get the venue_type from the feature's venue_type property
'text-field': ['get','venue_type'],
'text-allow-overlap': true,
'text-font': [
'Open Sans Semibold',
'Arial Unicode MS Bold'
],
'text-offset': [0, 0.5],
'text-anchor': 'top'
}
});
callback();
});
with a GeoJson FeatureCollection of the following structure:
"type": "Feature",
"properties": {
"dist": 0.25566043226822727,
"index": 758,
"location": 21.218387011937942,
"name": "Östersjön",
"venue_type": "coastline"
},
"geometry": {
"type": "Point",
"coordinates": [
18.3434769,
59.4563257
]
}
The line responsible for setting the text underneath the marker is the following, which uses a Mapbox GL JS expression to fetch the field 'venue_type' from the properties of the GeoJSON object.
'text-field': ['get','venue_type']
I figured I could just do something like
'text-field': translate[['get','venue_type']]
but it gives the error:
Error: layers.venues.layout.text-field: 'undefined' value invalid. Use null instead.
at Object.ri [as emitValidationErrors]
text-field can take both a string, variable and a mapbox expression. But I'm not really sure if I can access the properties of the feature being added in any other way than the expression above.
Having looked into modifying the expression, it appears to be possible to use arithmetics and stuff, but I can't really find any example of mixing JavaScript into the expression.
Looking for some pointers here, should I go about it a different way? Or am I missing something?
First, this is a symbol layer, not a Marker.
You can't execute arbitrary JavaScript expressions within Mapbox GL expressions.
You can use a match expression, like this:
'text-field': [`match', ['get', 'venue_type'],
'water', 'Waterway',
'city', 'City Center',
'school', 'Elementary School',
''
]

Restassured: How Can we compare each element in Json array to one particular Same value in Java using Hemcrest Matchers, not using Foreach loop

Restassured: How Can we compare each element in Json array to one particular Same value in Java using Hemcrest Matchers, not using Foreach loop.
{
"id": 52352,
"name": "Great Apartments",
"floorplans": [
{
"id": 5342622,
"name": "THE STUDIO",
"fpCustomAmenities": [
{
"displaySequence": 2,
"amenityPartnerId": "gadasd",
"display": true,
"leased": true
},
{
"displaySequence": 13,
"amenityPartnerId": "sdfsfd",
"display": true,
"leased": true
}
]
},
{
"id": 4321020,
"name": "THE First Bed",
"fpCustomAmenities": [
{
"displaySequence": 4,
"amenityPartnerId": "gadasd",
"display": true,
"leased": true
},
{
"displaySequence": 15,
"amenityPartnerId": "hsfdsdf",
"display": true,
"leased": true
}
]
}
]
}
I want to compare that Leased=true for all the leased nodes at all the levels in the json response...
I have working code...
List<List<Boolean>> displayedvaluesfpStandardAmenities =
when().get(baseUrl + restUrl).
then().statusCode(200).log().ifError().
extract().body().jsonPath().getList("floorplans.fpCustomAmenities.display");
for (List<Boolean> displayedStandardList : displayedvaluesfpStandardAmenities) {
for (Boolean isDisplayedTrue : displayedStandardList) {
softAssert.assertTrue(isDisplayedTrue);
}
}
But the issue is I need the code to be in simple format using either Hemcrest Matchers or Restaussred Matchers and try simplistic way like Below, ( which is not working)
when().get(baseUrl + restUrl).
then().assertThat().body("floorplans.fpCustomAmenities.display",equalTo("true"));
The error I am getting is
java.lang.AssertionError: 1 expectation failed.
JSON path floorplans.fpCustomAmenities.display doesn't match.
Expected: true
Actual: <[[true, true], [true, true]]>
So what I need is the that all thes 'display' nodes in the json response where ever it is need to compared with "true", so that my test can Pass.
I have an alternate solution like mentioned above, but All I need is working solution using matchers.
Assuming fpCustomAmenities arrays are not empty, you can use the following solution;
when().get(baseUrl + restUrl).then()
.body("floorplans.findAll { it }.fpCustomAmenities" + // 1st line
".findAll { it }.leased.each{ a -> println a }" + // 2nd line
".grep{ it.contains(false) }.size()", equalTo(0)); // 3rd line
Here from the 1st line, we return each object in fpCustomAmenities array.
From the 2nd line we get boolean value of leased in each fpCustomAmenities object to a boolean array ([true, true]).
Each boolean array is printed from .each{ a -> println a }. I added it only to explain the answer. It is not relevant to the solution.
From 3rd line we check whether, if there is a false in each boolean array. grep() will return only the arrays which has a false. And then we get the filtered array count. Then we check whether it is equal to 0.
Check groovy documentation for more details.
Or
This solution does not use any Matchers. But this works.
String responseBody = when().get(baseUrl + restUrl).
then().extract().response().getBody().asPrettyString();
Assert.assertFalse(responseBody.contains("\"leased\": false"));

Swagger query parameter template

I have on query parameter which is little bit complex and i have my own syntax to make that value. Its has more then one variable to make one complete string value.
Let suppose name of parameter is index which has row and column like to make this value 20:30
index = { row: 20, col:30 }
index2 = { row: 20, col:30, chr: 15 }
Now i wanted to make it as
example.com?index=20:30
example.com?index2=20:30:15
Can someone tell me how can i define this in swagger ?
Thank you.
Make your swagger parameter a string and in your code behind handle the splitting into multiple variables...
I do exactly that here:
http://turoapi.azurewebsites.net/swagger/ui/index#/Echo/Echo_Get
"parameters": [
{
"name": "location",
"in": "query",
"description": "SoFL= 26.16,-80.20",
"required": true,
"type": "string"
},
That location is (Latitude,Longitude) and I split it with a C# TypeConverter
...and the request looks like:
http://turoapi.azurewebsites.net/api/Echo?location=26.16,-80.20
The code for that WebApi is here:
https://github.com/heldersepu/TuroApi

JSON-LD normalization - ignore JSON nesting

I'm working on JSON-LD serialization, and ideally I would like to have a #context which I can add to the existing GeoJSON output (together with some #ids and #types), so that both the Turtle output and the JSON-LD output will normalize to the same triples.
Data is organized as follows: each object/feature has an ID and a name, and data on one or more layers. Per layer, there is a data field, which contains a JSON object.
Example GeoJSON output:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "admr.nl.appingedam",
"name": "Appingedam",
"layers": {
"cbs": {
"data": {
"name": "Appingedam",
"population": 1092
}
},
"admr": {
"data": {
"name": "Appingedam",
"gme_code": 4654,
"admn_level": 3
}
}
}
},
"geometry": {…}
}
]
}
Example Turtle output:
<admr.nl.appingedam>
a :Node ;
dc:title "Appingedam" ;
:createdOnLayer <layer/admr> ;
:layerData <admr.nl.appingedam/admr> ;
:layerData <admr.nl.appingedam/cbs> .
<admr.nl.appingedam/admr>
a :LayerData ;
:definedOnLayer <layer/admr> ;
<layer/admr/name> "Appingedam" ;
<layer/admr/gme_code> "4654" .
<layer/admr/admn_level> "3" .
<admr.nl.appingedam/cbs>
a :LayerData ;
:definedOnLayer <layer/cbs> ;
<layer/cbs/name> "Appingedam" ;
<layer/cbs/population> "1092" ;
The properties object does not have its own URI. Is there a way to create a JSON-LD context which takes the contents of the properties into account, but further 'ignores' its precence?
Answered by Gregg Kellogg on JSON-LD mailing list:
This is something that keeps coming up: having a transparent layer,
that basically folds properties up a level. This was discussed during
the development of JSON-LD, but ultimately it was rejected.
I don't see any prospects for doing something in the short-term, but
it could be revisited in a possible future WG chartered with revising
the spec. Feedback like this is quite useful.
In the mean time, you can play with different JSON-LD encodings that
match your RDF though tools like http://json-ld.org/playground and my
own http://rdf.greggkellogg.net/distiller.
Gregg

Resources