in my schema I set the size:
size: { type: bigint, required: true }
My generated 'base' model gives me:
public function setSize($v)
{
if ($v !== null) {
$v = (string) $v;
}
if ($this->size !== $v) {
$this->size = $v;
$this->modifiedColumns[] = TorrentPeer::SIZE;
}
return $this;
} // setSize()
Why does it case it to a string and not an integer?
I now receive the error:
"7818435653" is not an integer.
I tried changing the (string) to (int), but it did not work, I receive the same error. I'm confused why Propel made this value string when I specified bigint. Any help?
propel stores bigint as a string as PHP's integer type is too small: http://www.propelorm.org/wiki/Documentation/1.5/Schema#NumericTypes
Related
We couldn't pass a DateTime? value to a function that requires a DateTime argument.
The code below results in an error.
class Spacecraft {
String name;
DateTime? launchDate;
// Read-only non-final property
int? get launchYear => launchDate?.year;
// Constructor, with syntactic sugar for assignment to members.
Spacecraft(this.name, this.launchDate) {
// Initialization code go here.
}
// Named constructor that forwards to the default one.
Spacecraft.unlaunched(String name) : this(name, null);
// Method
void describe() {
print('Spacecraft: $name');
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
The argument type 'DateTime?' can't be assigned to the parameter type
'DateTime'.
However, this worked:
class Spacecraft {
String name;
DateTime? launchDate;
// Read-only non-final property
int? get launchYear => launchDate?.year;
// Constructor, with syntactic sugar for assignment to members.
Spacecraft(this.name, this.launchDate) {
// Initialization code go here.
}
// Named constructor that forwards to the default one.
Spacecraft.unlaunched(String name) : this(name, null);
// Method
void describe() {
print('Spacecraft: $name');
// Type promotion doesn't work on getters
var launchDate2 = launchDate;
if (launchDate2 != null) {
int years = DateTime.now().difference(launchDate2).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
And heck, launchDate2 is also a DateTime? type. Why the heck it could be passed to a function that requires a DateTime argument?
launchDate refers to a property so it couldn't be promoted or cast. See http://dart.dev/go/non-promo-property and also https://dart.dev/null-safety/understanding-null-safety
I am trying to get a list of students from the function seasonalStudents and use it in another function studentListener
I want to use unHapyyStd but in this line unHappyStd = [StaticStudents(std.id, null, TotalStudents(std.id, null))]; I get an error The argument type TotalStudents can't be assigned to the parameter Type List<TotalStudents> , How do I fix it ?
class Toppers {
String id;
double passmark;
double failmark;
Toppers(this.id, this.passmark, this.failmark);
}
class TotalStudents {
final String id;
final Image markerIcon;
TotalStudents(
this.id,
this.markerIcon,
);
}
class StaticStudents {
final String id;
final String call;
final List<TotalStudents> totalStds;
StaticStudents(this.id, this.call, this.totalStds);
}
class Students {}
class NearPassedStudents {
String id;
double passmark;
double failmark;
NearPassedStudents(this.id, this.passmark, this.failmark);
}
class GeoStudents {
static List<NearPassedStudents> passedStudentsList = [];
}
void seasonalStudents() {
for (NearPassedStudents std in GeoStudents.passedStudentsList) {
print("student: ${std.id}");
print("student: ${std.passmark}");
print("student: ${std.failmark}");
unHappyStd = [StaticStudents(std.id, null, TotalStudents(std.id, std.passmark))];
}
Future<void> studentListener()async{
////some method
/// use it here
case studentX:
seasonalStudents();
}
}
Your problem is that the third argument in the StaticStudents constructor expects the type List<TotalStudents> but you are sending a TotalStudents object as argument:
StaticStudents(std.id, null, TotalStudents(std.id, null))
Instead, make it a List with the following if you just want a list with a single TotalStudents to be used:
StaticStudents(std.id, null, [TotalStudents(std.id, null)])
As your 3rd argument require list instead of just obj. inside your loop you can do like this
var list = <TotalStudents>[];
list.add(TotalStudents(std.id, null));
unHappyStd = [StaticStudents(std.id, null, list)];
I am creating a simple smart contract, however, I am getting an error on my last function ("ViewNotes") stating that the compiler was "Expected Primary Expression"? Can I not check the value at a mapping (of address => string) against the value 0 ?
My code:
pragma solidity ^0.4.4;
contract Logistics{
address public owner;
mapping(address => string) notes;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
constructor(address genesis) public {
owner = genesis;
}
function sign(string signedNote) public onlyOwner{
notes[owner] = signedNote; //gaurenteed that msg.sender == owner
}
function transferOwnership(address nuOwner) onlyOwner {
owner = nuOwner;
}
function viewNotes(address participant) public returns(string){ // signed note on success nothing on fail
if(notes[participant] !== 0){
return (notes(participant));
}
}
}
There are a couple issues. The primary issue is that you misspelled !=. (You have an extra equals sign. !== is an operator in JavaScript, but not in Solidity.)
Once you fix that, you'll find that you can't compare a string to the number 0. You probably want to check the string's length? You'll need to cast to bytes to do that:
function viewNotes(address participant) public returns (string) {
if (bytes(notes[participant]).length != 0) {
return notes[participant];
}
}
That said, I believe this is probably equivalent to just:
function viewNotes(address participant) public returns (string) {
return notes[participant];
}
And you could instead just make notes public:
mapping(address => string) public notes;
That way, Solidity will generate a getter function for you, and people can just call notes(addr), making viewNotes redundant.
Fixing up a couple other warnings, getting rid of the modifier in favor of a direct ownership check, and assigning initial ownership to the deployer, here's my take on the contract:
pragma solidity ^0.4.24;
contract Logistics{
address public owner = msg.sender;
mapping(address => string) public notes;
function sign(string note) public {
require(msg.sender == owner);
notes[owner] = note;
}
function transferOwnership(address newOwner) public {
require(msg.sender == owner);
owner = newOwner;
}
}
I've found an example of how to bind Integer to a TextField:
Binder<Person> b = new Binder<>();
b.forField(ageField)
.withNullRepresentation("")
.withConverter(new StringToIntegerConverter("Must be valid integer !"))
.withValidator(integer -> integer > 0, "Age must be positive")
.bind(p -> p.getAge(), (p, i) -> p.setAge(i));
The problem is - there is no StringToCharacterConverter and if have an error if I bind fields as is. The error is:
Property type 'java.lang.Character' doesn't match the field type 'java.lang.String'. Binding should be configured manually using converter.
You need to implement custom converter, here is very simplified version of what could be StringToCharacterConverter for getting the pattern what the they look like:
public class StringToCharacterConverter implements Converter<String,Character> {
#Override
public Result<Character> convertToModel(String value, ValueContext context) {
if (value == null) {
return Result.ok(null);
}
value = value.trim();
if (value.isEmpty()) {
return Result.ok(null);
} else if (value.length() == 1) {
Character character = value.charAt(0);
return Result.ok(character);
} else {
return Result.error("Error message here");
}
}
#Override
public String convertToPresentation(Character value, ValueContext context) {
String string = value.toString();
return string;
}
}
I reproduced the issue I am having in a brand new MVC Web API project.
This is the default code with a slight modification.
public string Get(int? id, int? something = null)
{
var isValid = ModelState.IsValid;
return "value";
}
If you go to http://localhost/api/values/5?something=123 then this works fine, and isValid is true.
If you go to http://localhost/api/values/5?something= then isValid is false.
The issue I am having is that if you provide a null or omitted value for an item that is nullable, the ModelState.IsValid flags a validation error saying "A value is required but was not present in the request."
The ModelState dictionary also looks like this:
with two entries for something, one nullable, which I am not sure if it is significant or not.
Any idea how I can fix this so that the model is valid when nullable parameters are omitted or provided as null? I am using model validation within my web api and it breaks it if every method with a nullable parameter generates model errors.
It appears that the default binding model doesn't fully understand nullable types. As seen in the question, it gives three parameter errors rather than the expected two.
You can get around this with a custom nullable model binder:
Model Binder
public class NullableIntModelBinder : IModelBinder
{
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(int?))
{
return false;
}
ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null)
{
return false;
}
string rawvalue = val.RawValue as string;
// Not supplied : /test/5
if (rawvalue == null)
{
bindingContext.Model = null;
return true;
}
// Provided but with no value : /test/5?something=
if (rawvalue == string.Empty)
{
bindingContext.Model = null;
return true;
}
// Provided with a value : /test/5?something=1
int result;
if (int.TryParse(rawvalue, out result))
{
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value to int");
return false;
}
}
Usage
public ModelStateDictionary Get(
int? id,
[ModelBinder(typeof(NullableIntModelBinder))]int? something = null)
{
var isValid = ModelState.IsValid;
return ModelState;
}
Adapted from the asp.net page: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api for further reading and an alternative method to set it at the class(controller) level rather than per parameter.
This handles the 3 valid scenarios:
/test/5
/test/5?something=
/test/5?something=2
this first give "something" as null. Anything else (eg ?something=x) gives an error.
If you change the signature to
int? somthing
(ie remove = null) then you must explicitly provide the parameter, ie /test/5 will not be a valid route unless you tweak your routes as well.
You'll have to register a custom model-binder for nullable types as the default binder is calling the validator for nullable parameters as well, and the latter considers those empty values as invalid.
The Model Binder:
public class NullableModelBinder<T> : System.Web.Http.ModelBinding.IModelBinder where T : struct
{
private static readonly TypeConverter converter = TypeDescriptor.GetConverter( typeof( T ) );
public bool BindModel( HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext )
{
var val = bindingContext.ValueProvider.GetValue( bindingContext.ModelName );
// Cast value to string but when it fails we must not suppress the validation
if ( !( val?.RawValue is string rawVal ) ) return false;
// If the string contains a valid value we can convert it and complete the binding
if ( converter.IsValid( rawVal ) )
{
bindingContext.Model = converter.ConvertFromString( rawVal );
return true;
}
// If the string does contain data it cannot be nullable T and we must not suppress this error
if ( !string.IsNullOrWhiteSpace( rawVal ) ) return false;
// String is empty and allowed due to it being a nullable type
bindingContext.ValidationNode.SuppressValidation = true;
return false;
}
}
Registration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ...
var provider = new SimpleModelBinderProvider(typeof(int?), new NullableModelBinder<int>());
config.Services.Insert(typeof(ModelBinderProvider), 0, provider);
// ...
}
}
Remove the default null value from the second parameter. The model binder will set it to null if it's something other than int.
I've found a working workaround for me (just exclude null values from data being sent - as opposed to sending values as nulls).
See https://stackoverflow.com/a/66712465/908608