I have an MVC app where a user can select company benfits, there are 10 different benefits and they can have none up to all 10 of these. In my view I have the ten listed with radio buttons to indicate whether they are required or not. There is also a calculation performed in the controller that adds all the values together to give a total.
As an example in my controller -
newuser.LifeAssurance.LifeAssuranceRequired = viewModel.LifeAssuranceRequired;
newuser.LifeAssurance.LifeAssuranceSchemeName = viewModel.LifeAssuranceSchemeName;
newuser.LifeAssurance.LifeAssuranceProviderName = viewModel.LifeAssuranceProviderName;
newuser.LifeAssurance.LifeAssuranceBenefitLevel = viewModel.LifeAssuranceBenefitLevel;
newuser.LifeAssurance.LifeAssuranceEmployerCost = viewModel.LifeAssuranceEmployerCost;
newuser.LifeAssurance.LifeAssuranceEmployeeCost = viewModel.LifeAssuranceEmployeeCost;
Since the user may decide not to choose this benefit is it possible to assign the cost as 0 if they have not made a selection in the view model? Can I check if it's null and add 0 in that case?
You can use the ?? operator (see here)
use it like this:
string someString = null;
string someOtherString = someString ?? "0";
if someString(or any other object) is not null use it, else use whatever is on the right of the ?? operator.
Maybe set your values as nullable by add ? to type, and then you can check it is null by:
var someValue = (nullableValue.HasValue) ? nullableValue.Value : 0;
Related
I thought this would have been easy but I am having issues ticking all the boxes that I need in this.
I need to
Serialize an object to Json
Ignore any properties not set
Use the ENum names instead of integer values
I have generated all the models for this using the Open API Generator based on a .yaml spec.
My first attempt was to get a bit of code from what looks like an old serializer
let json<'t> (myObj:'t) =
use ms = new MemoryStream()
let serialiser: DataContractJsonSerializer = new DataContractJsonSerializer(typeof<'t>)
let settings: DataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
(new DataContractJsonSerializer(typeof<'t>)).WriteObject(ms, myObj)
Encoding.Default.GetString(ms.ToArray())
This function actually does everything fine - except it copiess the enum numbers instead of names and I can't see an option to make this happpen.
My other attempt is using System.Text.Json.JsonSerializer:
let options
= new JsonSerializerOptions(
)
options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingDefault
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
let jsonString:string = JsonSerializer.Serialize(shipmentRequest, options)
I have tried a few different things ( including excluding the Enum converter ) and I always get the following error.
Unable to cast object of type 'System.Int32' to type
'System.Nullable`1[Zimpla.Model.ExpressPackageReference+TypeCodeEnum]'
The specific Object ( roughly ) that it is having an issue with is:
[DataContract(Name = "ExpressPackageReference")]
public partial class ExpressPackageReference : IEquatable<ExpressPackageReference>, IValidatableObject
{
......etc
[DataMember(Name = "typeCode", EmitDefaultValue = false)]
public TypeCodeEnum? typeCode
{
get{ return _typeCode;}
set
{
_typeCode = value;
_flagtypeCode = true;
}
}
This particular property is not even set so it should be skipping over it theoretically. It is possible that I am not generating the object correctly
Without understanding all the details here, I think you are asking how you can serialize an object to json while omitting all properties that are null using System.Text.Json.
To accomplish that you have to set the following option:
options.IgnoreNullValues <- true
Here are the docs for this option:
https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.ignorenullvalues?view=net-5.0#System_Text_Json_JsonSerializerOptions_IgnoreNullValues
I'm trying to implement code in swift which will give me the closest date from current date.
The thing is I want users to choose in maximum 3 dates, and every time he chooses the date is added to the array named "reminders"
Then I check how many items (max 3) are in this array (named: reminders), and store the particular date/ dates from the array using CoreData:
if addObjectView.reminders.count == 1 {
newobject.firstReminder = addObjectView.reminders[0]
}
if addObjecteView.reminders.count == 2 {
newobject.firstReminder = addObjectView.reminders[0]
newobject.secondReminder = addObjectView.reminders[1]
}
if addObjectView.reminders.count == 3 {
newobject.firstReminder = addObjectView.reminders[0]
newobject.secondReminder = addObjectView.reminders[1]
newobject.thirdReminder = addObjectView.reminders[2]
}
Then I want to implement code to check first if the first/second/thirdReminder from CoreData is nil, and if it's not then compare it to current date. If it is 'larger' then set String from this date as label. But I want also to compare date from first/second/thirdReminder between themselves or somehow make sure that the firstReminder will always be earlier than second and so on.
I don't know if it is that hard, but I'm trying to figure it out and I'm stuck.
You should use the nil coalescing operator for this purpose.
The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.
Source - developer.apple.com
You could get the reminder's date, stored in myOptionalDate, and check if it is nil. If it is, then we will do
0 > NSDate().timeIntervalSince1970
which will always be false. If it isn't nil, we can do the equivalent of
myOptionalDate!.timeIntervalSince1970 > NSDate().timeIntervalSince1970
which will tell you if you if the label should be added
if((myOptionalDate?.timeIntervalSince1970 ?? 0) > NSDate().timeIntervalSince1970){
//add the label
}
Which is shorthand for
var myInterval = 0
if(myOptionalDate != nil){
myInterval = myOptionalDate!.timeIntervalSince1970
}
if(myInterval > NSDate().timeIntervalSince1970)
Also, although this doesn't have to do with the question, depending on how your code is formatted, you shouldn't have to use if statements to check how many reminders there are
By default, newobject.firstReminder, newobject.secondReminder, and newobject.thirdReminder will (I'm assuming) be nil. So, you could just change all of your example code to
let originalReminders = addObjectView.reminders
newobject.firstReminder = originalReminders.count > 0 ? originalReminders[0] : nil
newobject.secondReminder = originalReminders.count > 1 ? originalReminders[1] : nil
newobject.thirdReminder = originalReminders.count > 2 ? originalReminders[2] : nil
if the default value isn't nil, you could simply replace nil in the above code with your default value
I need to get list of instances. I did so to do this:
def availableCafee = Cafee.list()
But now, my task is complicated. It requires if certain field in instance doesn't have an empty string value, other fields of the instance must be found via some controller and the other instance by this string value. Domain class is below.
If apiInit is empty, the instance added to list how in example above, if apiInit isn't empty, it assumed other fields wasn't initialized, so getting other fields requires via controller, which I've done and the other instance.So external API work is emulate. How to change example above to do this?
class Cafee {
String cafeeName = ""
int totalReservationPlaces = 0
double placeCost = 0
String currencyType = ""
boolean isReservationAvailable = false
boolean reservationTimeLimit = false
boolean reservationDateLimit = false
int totalPlaces = 0
LocalTime startTimeLimit = new LocalTime()
LocalTime endTimeLimit = new LocalTime()
Date startDateLimit = new Date()
Date endDateLimit = new Date()
String region = ""
String city = ""
String apiInit = ""
}
I think what you are trying to say is that a nullable object is causing the object not to be saved.
The solution is quite simple:
static constraints = {
apiInit nullable: true
}
Have a read here: rejected-value-null
So ideally set all those objects that are could be nullable should be set
ChatUser.groovy
you can also set the defaultValue of an object in the mapping:
MailingListBase.groovy
Please note if it is an already generated Database table any attempt now to set to nullable after it has been previously created will not work. you will either have to set this manually or drop it and let it regenerate..
Can somebody give me an example of how to make inserting data into an F# record more flexible?
I often see examples using records like this:
type Employee = {mutable name:string; mutable id:string}
let data =
[{name = "Thomas";id = "000"};
{name = "Johny";id = "001"};
{name = "Lucky";id = "002"};
{name = "Don";id = "003"}
]
Can't we start with no data at all and insert the data into the record later?
(What I mean is without declaration of the value of the data like in the example, so for example: the program is running and asking us to insert the data)
Can we doing something like this with record?
If you're talking about specifying values of a record as they become available, then you need to make fields of the record option so that you can represent the fact that value is missing. I'll use immutable records, because this is more common in functional style:
type Employee = { Name:option<string>; ID:option<string> }
Now you can create a record with only ID and add name when the user enters it:
let empty = { Name = None; ID = Some 123 }
let name = // read name from user
let full = { empty with Name = name }
If you're talking about adding items to a list as they become available, then you have several options. The direct one is to write a recursive function that repeatedly reads record and builds a list:
let rec readData i records =
let name = // read name from user
if name <> "" then
// Create new record and add it to our list
let itm = { Name = name; ID = string i }
readData (i + 1) (itm::records)
else
// Return records that we collected so far in the right order
records |> List.rev
Alternatively, you can also use sequence expressions (see for example free Chapter 12 (PDF) of Real-World Functional Programming). If you user interaction involves waiting for events (e.g. mouse click), then you can still use this style, but you'd need to wrap everything in asynchronous workflow and use Async.AwaitEvent.
Are you saw you often saw an example like that?
I'd say that it is not very idiomatic in F# to use mutable records.
Immutability is a rather large subject
to explain in one answer here, but
briefly: immutability means that the
objects you create never change:
they stay the way they were at
creation. In the immutable world, when
you want to 'change' something, you
create a new one, and throw away the
old one.
Anyway, if I understand your question correctly, you are actually talking about mutating data, not the record. So, you could have:
let data = []
let data = {name = "Thomas";id = "000"} :: data
let data = {{name = "Johny";id = "001"} :: data
But in this case, you aren't really 'changing' data, you are just creating a new list each time and pointing data at it.
Its a little tricky to search for 'var:*' because most search engines wont find it.
I'm not clear exactly what var:* means, compared to say var:Object
I thought it would let me set arbitrary properties on an object like :
var x:* = myObject;
x.nonExistantProperty = "123";
but this gives me an error :
Property nonExistantProperty not found on x
What does * mean exactly?
Edit: I fixed the original var:* to the correct var x:*. Lost my internet connection
Expanding on the other answers, declaring something with type asterisk is exactly the same as leaving it untyped.
var x:* = {};
var y = {}; // equivalent
However, the question of whether you are allowed to assign non-existant properties to objects has nothing to do with the type of the reference, and is determined by whether or not the object is an instance of a dynamic class.
For example, since Object is dynamic and String is not:
var o:Object = {};
o.foo = 1; // fine
var a:* = o;
a.bar = 1; // again, fine
var s:String = "";
s.foo = 1; // compile-time error
var b:* = s;
b.bar = 1; // run-time error
Note how you can always assign new properties to the object, regardless of what kind of reference you use. Likewise, you can never assign new properties to the String, but if you use a typed reference then this will be caught by the compiler, and with an untyped reference the compiler doesn't know whether b is dynamic or not, so the error occurs at runtime.
Incidentally, doc reference on type-asterisk can be found here:
http://livedocs.adobe.com/labs/air/1/aslr/specialTypes.html#*
(The markup engine refuses to linkify that, because of the asterisk.)
It's a way of specifying an untyped variable so that you can basically assign any type to it. The code
var x:* = oneTypeObject;
creates the variable x then assigns the oneTypeObject variable to it. You can assign an entirely different type to it as well as follows:
var x:* = anotherTypeObject;
However, you still can't arbitrarily set or access properties; they have to exist in the underlying type (of either oneTypeObject or anotherTypeObject).
Both types may have identically named properties which means you can access or set that property in x without having to concern yourself with the underlying type.
It's the "untyped" type. It just means that the variable can be of any type. Basically the same effect as using this:
var x = myObject;
It means that the type is not specified and can be used with any type. However, you can't set random properties on it. It will behave like whatever type you set it to. The exact syntax is:
var x:*;
As they said before, it's untyped, so it may hold any kind of data. However, you cannot treat it as such in operations. For example, this is valid code:
var untyped:* = functionThatReturnsSomeValue();
But if you go one step farther, you have to watch out or you might get bitten:
var name:String = untyped.name;
Now, if the object returned by that function happens to be an object with a field with an id of "name," you are in the clear. However, unless you know for sure that this is the case, it's better to use typed objects. In this way, the compiler will alert you if you do something that might throw an error at runtime:
(elsewhere)
public class TypedObject()
{
public var name:String = "";
}
(and the code at hand)
var typed:TypedObject = functionThatReturnsTypedObject();
var name:String = typed.name;