DynamoDB ValidationException: A value provided cannot be converted into a number - amazon-dynamodb

I have very strange behavior in my Nest.js application with dynamoose. This is my location schema:
import { NULL, Schema } from 'dynamoose';
export const LocationSchema = new Schema({
country: String,
city: String,
zipCode: String,
companyName: {
type: [String, NULL],
default: null,
},
streetAddress: {
type: [String, NULL],
default: null,
},
contactPhone: {
type: [String, NULL],
default: null,
},
contactEmail: {
type: [String, NULL],
default: null,
},
});
In body I'm posting this:
"deliveryLocation":{"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"},"pickupLocation":{"country":"Belgium","zipCode":"1020","city":"BRUXELLES/BRUSSEL 2"}
And I got ValidationException: A value provided cannot be converted into a number
As you can see any property has type Number.
What is even more strange if I change in deliveryLocation zipCode to M119 it is valid for DynamoDB.
If I'm changing in deliveryLocation United Kingdom to 'United Kindon' and let zipCode stay 'M11 9' the error is not coming.
If I making request with same values in deliveryLocation and pickupLocation - {"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"} - there is also no error.
To sum up error occurs only in this combination
"deliveryLocation":{"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"},"pickupLocation":{"country":"Belgium","zipCode":"1020","city":"BRUXELLES/BRUSSEL 2"}
Any idea why it is happening?
I tried adding to schema
saveUnknown: true,
but it is not solving the problem.

Related

dynamodb add item to the array list

Using serverless-stack.
I have a table company with multiple branches:
new sst.Table(this, 'Company', {
fields: {
userId: sst.TableFieldType.STRING,
companyId: sst.TableFieldType.STRING,
companyName: sst.TableFieldType.STRING,
branches: [
{
branchId: sst.TableFieldType.STRING,
branchName: sst.TableFieldType.STRING
}
]
},
primaryIndex: {partitionKey: "userId", sortKey: "companyId"}
})
I am trying to add branch to the branches:
const branch = {
branchId: uuid.v1(),
branchName: data.branchName
}
const params = {
TableName: process.env.COMPANY_TABLE_NAME,
Key: {userId: "1", companyId: data.companyId},
UpdateExpression: "ADD #branches :branch",
ExpressionAttributeNames: { "#branches" : "branches" },
ExpressionAttributeValues: { ":branch": [branch] }
}
But I get this error:
ERROR ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST, typeSet: ALLOWED_FOR_ADD_OPERAND
ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST, typeSet: ALLOWED_FOR_ADD_OPERAND
ADD is only for numbers and sets. Your branches attribute is a list. So you can use SET with list_append.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements
SET #branches = list_append(#branches, :branch) is correct. But ExpressionAttributeValues should be ExpressionAttributeValues: { ":branch": {"L":[branch]}}
You can refer to https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.update_item

Query backlink on two fields with same type

I have a relationship between Product and its units describe in schema as below:
public static schema: Realm.ObjectSchema = {
name: Product.schemaName,
primaryKey: 'sku',
properties: {
name: {type: 'string'},
baseUnit: {type: SoldableUnit.schemaName},
derivedUnits: {type: 'list', objectType: SoldableUnit.schemaName},
},
};
public static schema: Realm.ObjectSchema = {
name: SoldableUnit.schemaName,
embedded: true,
properties: {
unitName: {type: 'string'},
sellingPrice: {type: 'double'},
weight: {type: 'float'},
barcode: {type: 'string', optional: true, indexed:true},
},
};
The idea is a product can have one baseUnit and many derivedUnits, and both baseUnit and derivedUnits are SoldableUnit with the same schema. I want to query product by barcode. Here I have to return the product, providing a barcode which maybe equals to barcode of baseUnit or derived units. After some research, I find out that I can use backlink to return inverse relationship. The problem here is SoldableUnit occurs both in baseUnit and derivedUnits and I dont know how to achieve this goals? And whether the schema design of Product is appropriate?

Aldeed Simple-Schema, how to use allowed values in a field from another one?

I am trying to build a kind of specific simple schema for a collection and i would like to make sure that :
when the user enter a new select in my selectsCollection, he will put one of the options value as selected value.
For example:
SelectsCollection.insert({name:"SelectOne",deviceType:"Select",options:["option1","option2","option3"],value:"option4",description:"This is the first select"});
this do not have to work. I want him to write only one of the 3 options.
Here my schema :
SelectsCollection = new Mongo.Collection('Selects'); //Create a table
SelectsSchema = new SimpleSchema({
name:{
type: String,
label:"Name",
unique:true
},
deviceType:{
type: String,
allowedValues: ['Select'],
label:"Type of Device"
},
options:{
type: [String],
minCount:2,
maxcount:5,
label:"Select Values"
},
value:{
type: String,
//allowedValues:[options] a kind of syntax
// or allowedValues:function(){ // some instructions to retrieve the array of string of the option field ?}
label:"Selected Value"
},
description:{
type: String,
label:"Description"
},
createdAt:{
type: Date,
label:"Created At",
autoValue: function(){
return new Date()
}
}
});
SelectsCollection.attachSchema(SelectsSchema);
Any Idea ? :)
Thanks a lot !
This could be done with custom validation function of a field, inside this function you could retrieve values from other fields:
SelectsSchema = new SimpleSchema({
// ...
options: {
type: [String],
minCount: 2,
maxcount: 5,
label: "Select Values"
},
value: {
label: "Selected Value",
type: String,
optional: true,
custom() {
const options = this.field('options').value
const value = this.value
if (!value) {
return 'required'
}
if (options.indexOf(value) === -1) {
return 'notAllowed'
}
}
},
// ...
});
Look here custom-field-validation for more information

Subschema as array item with AutoForm, SimpleSchema

I am trying to get subschemas to work as an array, which I assume is the correct way to handle my problem (but please correct me if I am wrong!). I provide a simplified working example to show my problem, based on the BooksSchema example provided by the AutoForm package. In my example, I have a collection of Libraries, and one of the fields in the 'Libraries' object is supposed to be the library's collection of books. Rendering the AutoForm does not give me any input labels as defined in my Book collection, but instead just shows one (1) empty text input field.
Schemas:
import SimpleSchema from 'simpl-schema';
SimpleSchema.extendOptions(['autoform']);
BooksSchema = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
author: {
type: String,
label: "Author"
},
copies: {
type: Number,
label: "Number of copies",
min: 0
},
lastCheckedOut: {
type: Date,
label: "Last date this book was checked out",
optional: true
},
summary: {
type: String,
label: "Brief summary",
optional: true,
max: 1000
}
}, { tracker: Tracker });
LibrariesSchema = new SimpleSchema({
collection: {
type: Array
},
'collection.$': {
type: BooksSchema,
minCount: 1
}
});
LibrariesSchema.extend(BooksSchema);
Libraries = new Mongo.Collection("libraries");
Libraries.attachSchema(LibrariesSchema);
AutoForm:
{{> quickForm collection="Libraries" id="insertBookForm" type="insert"}}
Thank you so much in advance for your time, really been struggling with this for a long time now!
In my case I was indeed able to resolve the issue by using John Smith's example without the brackets.
LibrariesSchema = new SimpleSchema({
'books': {
type: BooksSchema,
minCount: 1
}
});
LibrariesSchema = new SimpleSchema({
'books': {
type: [BooksSchema],
minCount: 1
}
});
Arrays of a specific types, for use in check() or schema definitions, are specified as [SomeType], eg. [String], or [BooksSchema] in your case.

Any way to have Simple Schema in Meteor validate a specific array index?

From what I understand in the docs, you can define your schema like this:
MySchema = new SimpleSchema({
//This says that the addresses key is going to contain an array
addresses: {
type: [Object],
},
// To indicate the presence of an array, use a $:
"addresses.$.street": {
type: String,
},
"addresses.$.city": {
type: String,
}
});
Ok, I get this part. But what if I wanted to validate the contents in a specific array index? I want something like this:
MySchema = new SimpleSchema({
//This says that the itemsOrdered key is going to contain an array
itemsOrdered: {
type: [Object],
},
// Here I want to validate certain indexes in the array.
"itemsOrdered.0.sku": {
type: String
},
"itemsOrdered.0.price": {
type: Number
},
"itemsOrdered.1.sku": {
type: String
},
"itemsOrdered.1.price": {
type: Number
},
"itemsOrdered.1.quantity": {
type: Number
},
"itemsOrdered.2.sku": {
type: String
},
"itemsOrdered.2.price": {
type: Number
},
"itemsOrdered.2.customerNotes": {
type: String
optional: true
}
});
So here I'm trying to validate the values inside array index 0, 1, and 2. Each array index has a different item that has been ordered.
Normally I would use a hash table data structure, but for this purpose I need to preserve order which is why I'm using an array.
When I try to run this code I get an error Cannot read property 'blackbox' of undefined
Have you considered custom validation?
https://github.com/aldeed/meteor-simple-schema/blob/master/README.md#custom-validation
According to the doc within the function the key property of this will provide the information you want. So you could have something like:
MySchema = new SimpleSchema({
//This says that the itemsOrdered key is going to contain an array
itemsOrdered: {
type: [Object],
},
// Here I want to validate certain indexes in the array.
"itemsOrdered.$.sku": {
type: String,
custom: function () {
var key = this.key,
re = /\d+/;
var index = Number(key.match(re)[0]);
// Do some custom validation
}
},
"itemsOrdered.$.price": {
type: Number
},
"itemsOrdered.$.quantity": {
type: Number,
optional: true
},
"itemsOrdered.$.customerNotes": {
type: String,
optional: true
}
});
Here I put the validation logic in the sku field since it's required.

Resources