class validator not working with class transformer's type function - class-validator

class Product {
#Min(0, { message: 'should be positive number' })
#IsNotEmpty({ message: 'should not be empty' })
#Type(() => Number)
price: number;
}
*In this case, price come from input value, so it should be string at first.
I want to show error message that following cases by class-validator, but only #IsNotEmpty not working.
If field is empty, show 'should not be empty'
If field is not empty && field value is negative, show 'should be positive number'
why #IsNotEmpty not working with #Type type function?

I think you have mixed up class-validator and class-transformer's decorators.
My understanding is that #Type is solely used by class-transformer to aid in transforming the type of a nested object. That issue aside, I believe the order in which you declare your validators matters. This should work:
class Product {
#IsNotEmpty({ message: 'should not be empty' })
#Min(0, { message: 'should be positive number' })
price: number;
}

Related

Why does the map method for the List class in flutter not work anymore?

I opened my project one day and multiple files had errors were there were none before. All of the errors were due to the map method for the list class.
The error says: "The method 'map' isn't defined for the type 'List'."
If there is no way of getting the map method to work, how should I work around this issue?
Code Snippet:
// User list from snapshot
List<TestUser> _userListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc){
return TestUser(
name: doc.data()['name'] ?? '',
year: doc.data()['year'] ?? 0,
school: doc.data()['school'] ?? 'School',
);
}).toList();
}
Try to add object type
return snapshot.docs.map<TestUser>((doc){

Type restriction for class members in case/when

Let's say I have following class Message representing a message in a chat.
class Message
JSON.mapping({
message_id: {type: Int32},
text: {type: String, nilable: true},
photo: {type: Photo, nilable: true},
sticker: {type: Sticker, nilable: true},
})
MESSAGE_TYPES = %w( text photo sticker )
{% for type in MESSAGE_TYPES %}
def {{ type.id }}?
! {{ type.id }}.nil?
end
{% end %}
end
Every message can be either text, or photo, or sticker. But only one of those. For instance, if message is a text, then photo and sticker properties are nil, but text is not nil. If message is a sticker, only sticker is not nil. And so on. Real class has much more direct types and inferred types.
Upon receiving this message, I want to process it in a way specific for particular type. Something like:
case message
when .text?
p message.text
when .photo?
p message.photo.file_id
when .sticker?
p message.sticker.file_id
end
Of course, it won't work, because in each when clause corresponding properties are nilable and undefined method 'file_id' for Nil.
Is there any way to restrict variable type in each case making sure that is message.sticker? then message.sticker is not nil and file_id exists?
Maybe I'm completely wrong in very approaching the problem and there better and cleaner ways to code this?
require "json"
class Photo
JSON.mapping(url: String)
end
struct Message
JSON.mapping(id: Int32, message: String|Photo)
end
p Message.from_json(%({"id": 5, "message": {"url": "http://example.org/"}}))
You could put all payload objects in one instance variable with a union type as Oleh Prypin suggested.
Another option, if you want to keep the current data layout, you could have the methods return the respective Type or nil and assign its value to a variable:
if text = message.text?
p text
if photo = message.photo?
p photo.file_id
if sticker = message.sticker?
p sticker.file_id
end

How to map JSON::Any to custom Object in Crystal language?

How to map parsed JSON as JSON::Any type to custom Object?
In my case, I am working on chat client. Chat API can respond to requests with following JSON:
{"ok" => true,
"result" =>
[{"update_id" => 71058322,
"message" =>
{"message_id" => 20,
"from" => "Benjamin",
"text" => "hey"}}]}
Somewhere inside my API client code I parse these JSON to perform some basic health checks and pass the result to response consumer. In the consumer, I iterate over result array and try to convert each update to appropriate object:
module Types
class Update
JSON.mapping({
update_id: {type: Int32},
message: {type: Message},
})
end
end
module Types
class Message
JSON.mapping({
message_id: Int32,
date: Int32,
text: String,
})
end
end
return unless response["ok"]
response["result"].each do |data|
update = Types::Update.from_json(data)
end
Unfortunately, last line results in compile error:
no overload matches 'JSON::Lexer.new' with type JSON::Any
Apparently, Object.from_json can accept only String JSONs, but not parsed JSON. In my case data is JSON::Any object.
Dirty fix Types::Update.from_json(data.to_json) works, but it looks ridiculous.
What is the proper way to map JSON object to custom type preserving all nested structure?
JSON.mapping doesn't work nicely together with JSON.parse. To solve your problem you can create another mapping Types::Result and parse a hole json using Object.from_json which is even much more convenient to work with:
module Types
class Message
JSON.mapping(
message_id: Int32,
text: String
)
end
class Update
JSON.mapping(
update_id: Int32,
message: Message
)
end
class Result
JSON.mapping(
success: { key: "ok", type: Bool },
updates: { key: "result", type: Array(Update) }
)
end
end
result = Types::Result.from_json string_json
result.success # => true
result.updates.first.message.text # => "hey"

How do I get programmatic error codes from Cognito?

I'm using the Cognito Javscript SDK, and I've created a form where a user can register an account. If, for whatever reason, server-side validation fails, the response looks like this:
{
"__type":"InvalidParameterException",
"message":"4 validation errors detected: Value at 'password' failed to satisfy constraint: Member must have length greater than or equal to 6; Value at 'password' failed to satisfy constraint: Member must satisfy regular expression pattern: [\\S]+; Value at 'username' failed to satisfy constraint: Member must have length greater than or equal to 1; Value at 'username' failed to satisfy constraint: Member must satisfy regular expression pattern: [\\p{L}\\p{M}\\p{S}\\p{N}\\p{P}]+"
}
The problem with this response is that I can't provide good user feedback because I'd have to parse the response to determine which fields need to be fixed. Is there a way to get the errors back in a format that is better for working with programmatically?
The best way to do this at the moment, is to programmatically grab the values by cutting out the substrings after 'value at'.
I haven't got an example of any library that might help in doing this but this is good feedback though.
Just in case anyone is stumbling on this ages later, the answer is to use response.code:
this.cognitoUser.forgotPassword({
onSuccess: (data) => {
},
onFailure: (data) => {
console.log(data)
/*
{
"__type":"InvalidParameterException",
"message":"4 validation errors etc"
}
*/
console.log(data.code)
/*
"InvalidParameterException"
*/
}
})
You have to first json stringify and then json parse the object to get values.
Try following sample code -
var errorObj = JSON.parse(JSON.stringify(data));
console.log(errorObj.statusCode);

What's the standard pattern for ember-data validations? (invalid state, becameInvalid...)

I've kinda been struggling with this for some time; let's see if somebody can help me out.
Although it's not explicitly said in the Readme, ember-data provides somewhat validations support. You can see that on some parts of the code and documentation:
https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/states.js#L411
https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/states.js#L529
The REST adapter doesn't add validations support on itself, but I found out that if I add something like this in the ajax calls, I can put the model on a "invalid" state with the errors object that came from the server side:
error: function(xhr){
var data = Ember.$.parseJSON(xhr.responseText);
store.recordWasInvalid(record, data.errors);
}
So I can easily to the following:
var transaction = App.store.transaction();
var record = transaction.createRecord(App.Post);
record.set('someProperty', 'invalid value');
transaction.commit()
// This makes the validation fail
record.set('someProperty', 'a valid value');
transaction.commit();
// This doesn't trigger the commit again.
The thing is: As you see, transactions don't try to recommit. This is explained here and here.
So the thing is: If I can't reuse a commit, how should I handle this? I kinda suspect that has something to do to the fact I'm asyncronously putting the model to the invalid state - by reading the documentation, it seems like is something meant for client-side validations. In this case, how should I use them?
I have a pending pull request that should fix this
https://github.com/emberjs/data/pull/539
I tried Javier's answer, but I get "Invalid Path" when doing any record.set(...) with the record in invalid state. What I found worked was:
// with the record in invalid state
record.send('becameValid');
record.set('someProperty', 'a valid value');
App.store.commit();
Alternatively, it seems that if I call record.get(...) first then subsequent record.set(...) calls work. This is probably a bug. But the above work-around will work in general for being able to re-commit the same record even without changing any properties. (Of course, if the properties are still invalid it will just fail again.)
this may seem to be an overly simple answer, but why not create a new transaction and add the pre-existing record to it? i'm also trying to figure out an error handling approach.
also you should probably consider writing this at the store level rather than the adapter level for the sake of re-use.
For some unknown reason, the record becomes part of the store default transaction. This code works for me:
var transaction = App.store.transaction();
var record = transaction.createRecord(App.Post);
record.set('someProperty', 'invalid value');
transaction.commit()
record.set('someProperty', 'a valid value');
App.store.commit(); // The record is created in backend
The problem is that after the first failure, you must always use the App.store.commit() with the problems it has.
Give a look at this gist. Its the pattern that i use in my projects.
https://gist.github.com/danielgatis/5550982
#josepjaume
Take a look at https://github.com/esbanarango/ember-model-validator.
Example:
import Model, { attr } from '#ember-data/model';
import { modelValidator } from 'ember-model-validator';
#modelValidator
export default class MyModel extends Model {
#attr('string') fullName;
#attr('string') fruit;
#attr('string') favoriteColor;
validations = {
fullName: {
presence: true
},
fruit: {
presence: true
},
favoriteColor: {
color: true
}
};
}