Adding dynamic maps in DynamoDB with Kotlin - kotlin

I'm using Spring Boot, Kotlin and CrudRepository to add items to my Dynamo Table.
The map I'm trying to add is dynamic, and can change attributes every single time.
I add the date of the object (delta) and save it, but I am having several errors:
When I save:
#DynamoDBTable(tableName = "delta_computers_inventory")
class DeltaComputersInventory(
#DynamoDBHashKey
#DynamoDBAttribute(attributeName = "delta_computers_inventory_id")
var id: String = UUID.randomUUID().toString(),
#DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.M)
#DynamoDBAttribute(attributeName = "delta")
var delta: Map<String, Any?> = mapOf(),
) {
#DynamoDBAttribute(attributeName = "date")
var date: String = OffsetDateTime.now(ZoneOffset.UTC).format(
DateTimeFormatter.ISO_DATE_TIME
)
}
and I do:
.doOnSuccess { listOfDocuments ->
deltaComputersRepository.saveAll(
listOfDocuments.map {
DeltaComputersInventory(
delta = it,
)
}
)
}
I get:
reactor.core.Exceptions$ErrorCallbackNotImplemented: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted
instead, if I do it through an Item (Item.fromMap(it))
#DynamoDBTable(tableName = "delta_computers_inventory")
class DeltaComputersInventory(
#DynamoDBHashKey
#DynamoDBAttribute(attributeName = "delta_computers_inventory_id")
var id: String = UUID.randomUUID().toString(),
#DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.M)
#DynamoDBAttribute(attributeName = "delta")
var delta: Item = Item(),
) {
#DynamoDBAttribute(attributeName = "date")
var date: String = OffsetDateTime.now(ZoneOffset.UTC).format(
DateTimeFormatter.ISO_DATE_TIME
)
}
I get no error, but my item in my DynamoDB shows empty:
{
"delta_computers_inventory_id": {
"S": "d389d63e-8e93-4b08-b576-e37fae9a4d58"
},
"date": {
"S": "2023-01-24T12:00:33.620015Z"
},
"delta": {
"M": {}
},
}
What am I doing wrong?

Related

Can I use optional parameter in path in Jetpack Compose Navigaiton?

I have this navigation graph
fun NavGraphBuilder.manageAvailabilityGraph() {
composable(
"availability/{id}",
arguments = listOf(
navArgument("id") {
type = NavType.StringType
nullable = true
},
),
) {
ManageAvailabilityScreen()
}
}
I thought I can use it for both
navHostController.navigate("availability")
navHostController.navigate("availability/123")
But first one does not work, I get
java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/availability } cannot be found in the navigation graph NavGraph(0x0) startDestination={Destination(0xcfbbf7da) route=home}
I fixed it by providing two different routes.
fun NavGraphBuilder.manageAvailabilityGraph() {
composable(
"availability",
) {
ManageAvailabilityScreen()
}
composable(
"availability/{id}",
arguments = listOf(
navArgument("id") {
type = NavType.StringType
nullable = true
},
),
) {
ManageAvailabilityScreen()
}
}
However, I want to know is if it is possible to combine both and just have one route with name "availability", so I don't need to repeat "availability"? And eseentially, both use the same screen.
I tried something like this but does not work.
fun NavGraphBuilder.manageAvailabilityGraph() {
composable(
"availability",
) {
ManageAvailabilityScreen()
navigation(startDestination = "{id}", "{id}") {
composable(
"{id}",
arguments = listOf(
navArgument("id") {
type = NavType.StringType
},
),
) {
ManageAvailabilityScreen()
}
}
}
}
You can mark id as the optional parameter in the route. Refer Documentation
fun NavGraphBuilder.manageAvailabilityGraph() {
composable(
"availability?id={id}",
arguments = listOf(
navArgument("id") {
type = NavType.StringType
nullable = true
},
),
) {
ManageAvailabilityScreen()
}
}
While navigating you can use,
navHostController.navigate("availability")
navHostController.navigate("availability?id=123")

FluentAssertions: collection subset should contain equivalent of list

I have a collection:
new[] { new { A = 5, PropIDontCareAbout = "XXX" }, new { A = 7, PropIDontCareAbout = "XXX" }, new { A = 9, PropIDontCareAbout = "XXX" } }
I want to check that it at least contains both new { A = 9 } and new { A = 5 } in any order.
I can use ContainEquivalentOf, but I have to do it one-by-one:
var actual = new[] {
new { A = 5, PropIDontCareAbout = "XXX" },
new { A = 7, PropIDontCareAbout = "XXX" },
new { A = 9, PropIDontCareAbout = "XXX" }
};
var expected = new [] { new { A = 5 }, new { A = 9 } };
foreach (var expectedItem in expected) {
actual.Should().ContainEquivalentOf(expectedItem);
}
Update: I can't use Contains because it requires actual and expected objects to have the same type.
I do not see an explicit solution. You can work-around using Select to create subject in the format of the expectation, then you can use
Contains(IEnumerable<T> expected, ...):
var actual = new[] {
new { A = 1, PropIDontCareAbout = "XXX" },
new { A = 7, PropIDontCareAbout = "XXX" },
new { A = 9, PropIDontCareAbout = "XXX" }
};
actual.Select(x => new { x.A }).Should()
.Contain(new[] { new { A = 9 }, new { A = 5 } });
In case of one the elements is not in the list you get a message like that:
Expected collection {{ A = 1 }, { A = 7 }, { A = 9 }}
to contain {{ A = 9 }, { A = 5 }},
but could not find {{ A = 5 }}.

How to save to TextField database transformed with visualTransformation

How to save to TextField database transformed with visualTransformation?
I have the following code:
var text by remember { mutableStateOf("") }
TextField(
value = text,
visualTransformation = DateTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = {
if (it.length < 9) text = it
}
)
Log.i("DATA",text)
the format is XX/XX/XXXX but when I send it to the database it loses the format and is XXXXXXXX
You can apply same transformations your VisualTransformation does using filter like this:
val visualTransformation: VisualTransformation = remember { DateTransformation() }
var text by remember { mutableStateOf("") }
Button(onClick = {
val transformedText = visualTransformation.filter(AnnotatedString(text)).text.text
// save to DB
}) {
}
TextField(
value = text, onValueChange = { text = it },
visualTransformation = visualTransformation
)

read data from Map<String, Object>

I get these type of data from some api. I want to read data from "FK_User" which seems an object, when
I read data like this i get this error:
The method '[]' isn't defined for the class 'Object'.
- 'Object' is from 'dart:core'.
print(a["FK_User"]["username"]);
and the data is like this:
var a = {
"ID": "dummyID",
"FK_User": {
"username": "dummyID",
},
"Somefield": "dymmy",
}
var b = a["FK_User"]["username"];
how can I read this type of data?
Map<String, dynamic> a = {
"ID": "dummyID",
"FK_User": {
"username": "dummyID",
},
"Somefield": "dymmy",
};
var b = a["FK_User"]["username"]; // dummyID
Map<String,dynamic> a_map = Map.castFrom(a);
Map<String,dynamic> fk_user_map = Map.castFrom(a_map["FK_user"]);

condition editing using .editable(..) datatables

Im new to datatables, and Im having this issue thats bugging me for a while.
for example, I'm trying to edit the 5th column, but I want to disable it for part of the rows..
is it possible? cause I don't seem to find the way..
$('td:eq('5')', oTable.fnGetNodes()).editable('/'+appName+'/GetGenWidgetTableDataServlet',
{
type : 'text',
tooltip: 'Click to Edit',
indicator: 'Saving...',
placeholder : '',
"callback": function( sValue, y ) {
var aPos = oTable.fnGetPosition( this );
oTable.fnUpdate( sValue, aPos[0], aPos[2],true,true );
},
"submitdata": function ( value, settings ) {
debugger
var iPos = oTable.fnGetPosition( this );
var colPos = iPos[2];
iPos = iPos[0];
if(iPos!=null)
{
var aData = oTable.fnGetData( iPos );
var vRowType = aData[0];
var iId = aData[2];
var moduleID = iId.split("$")[0];
var unitID = iId.split("$")[1];
var processID = iId.split("$")[2];
var riskID = iId.split("$")[3];
var controlID = iId.split("$")[4];
}
return {
"Token": idhref,
"moduleID" :moduleID,
"unitID": unitID,
"processID" :processID ,
"riskID": riskID,
"controlID": controlID,
"rowType":vRowType,
"Action": "saveRow",
"columnName": aoCols[colPos]["Id"]
};
},
"height": "25px",
"width": "50px"
}
We use the datatables editable plugin (https://code.google.com/p/jquery-datatables-editable/ ) and it allows you to set a sReadOnlyCellClass. We set that class in the datatable fnRowCallBack function based on the values in the row.
You could set an "editable" class in your fnRowCallBack
oTable = $('#resultTable').dataTable( {
...
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
if ( aData["something"] == "This row should be editable" )
{
nRow.className = "editable";
}
return nRow;
}
...
});
and modify your selector to
oTable.$('tr.editable td:eq(5)').editable( ...)