dart null safty issue when try to add value to map element - flutter

I am using Dart but i am facing null safty issue with following code
RxMap<Product,int>cartItems=Map<Product,int>().obs;
void updateCart(Product product,String type){
if(type=="plus") {
cartItems.value[product]++;
}
else {
cartItems.value[product]--;
}
}
i got the following error message
the method '+' can't be unconditionally invoked because the receiver can be 'null'
i tried to add null check to the target as following
cartItems.value![product]++;

You can give a default value if null.
cartItems.value[product]??0 +1
Or force assert to non null value like this.It may throw exception if element not present in HashMap
cartItems.value[product]!+1
In your question you are asserting not null for HashMap not the value of the HashMap.

The problem is that cartItems.value is a Map and it's possible that cartItems.value[product] is null. In this case you can't add or remove 1 to null.
So you should do like the following:
if (type == "plus") {
cartItems.value[product] = (cartItems.value[product] ?? 0) + 1;
} else {
cartItems.value[product] = (cartItems.value[product] ?? 0) - 1;
}
Using (cartItems.value[product] ?? 0) you're saying that if cartItems.value[product] is null 0 is used instead.
Also note that in the else clause, when cartItems.value[product] == null, you're trying to remove 1 to something that doesn't exist, so in that case it may be best to throw an exception:
int? currentValue = cartItems.value[product];
if (currentValue == null) {
throw Exception('Trying to remove on a null object');
}
cartItems.value[product] = currentValue - 1;

Related

returnMap[date]++; error : The method '+' can't be unconditionally invoked because the receiver can be 'null'

Hello I try to make null safety migration, but I have an error with ++ from returnMap[date]++; . I don't know how to write correctly in null stafety. Thank you
Here is my code
thank you
for (var i = x; i < list_conso.length; i++) {
DateTime parsedDate = DateTime.parse(list_conso[i]);
String date = "${parsedDate.year}-${parsedDate.month}-${parsedDate.day}";
date = DateFormat('yyyy-MM-dd').format(parsedDate);
if (returnMap.containsKey(date)) {
returnMap[date]++; //The method '+' can't be unconditionally invoked because the receiver can be 'null'
} else {
returnMap[date] = 1;
}
}
Since you have checked that returnMap contains date, you can use:
returnMap[date]!++;
The exclamation mark tells the compiler you are sure that returnMap[date] exists and is not null.

EF Core - detect actual property value changes

I'm attempting to detect which fields/properties/columns have changed in DbContext's SaveChanges() method. I'm currently using the following code:
string fields = "";
foreach (var entityProperty in ent.Entity.GetType().GetProperties())
{
var propertyName = entityProperty.Name;
var currentValue = ent.Property(propertyName).CurrentValue;
var originalValue = ent.Property(propertyName).OriginalValue;
if ( currentValue == null && originalValue != null ||
originalValue == null && currentValue != null ||
(currentValue != null && originalValue != null &&
!originalValue.Equals(currentValue))
)
{
fields += propertyName + ", ";
}
}
My code frequently sets the values of columns to their current value so I can't rely on PropertyEntry.IsModified - that seems to get set to true even if you set a field to the same value it already has.
Also, in the above code, originalValue is coming out as the NEW value of the column, so this code isn't working either.
Does anyone know how I can detect which fields/properties/columns have actually had their value changed?

Error: A value of type 'num?' can't be assigned to a variable of type 'num' because 'num?

I found this error while running the dart project
Error: A value of type 'num?' can't be assigned to a variable of type 'num' because 'num?'
import 'dart:io';
void main() {
print("Enter your birth-year");
var n = num.tryParse(stdin.readLineSync() ?? "");
if(n=="") {
print("Bad Year");
}
var age = DateTime.now().year-n;
print(" ==> You are $age year old!");
}
As you can read in the documentation of num.tryParse, the method has an return type of num?. This implies that your variable n is also of the type num? (Nullable num).
So the error points you to the line, where you want to subtract an nullable number from DateTime.now().year, which is not allowed.
You can workaround this limitation by using the ?? (Null coalescing) operator and checking for null and if your n is null subtract 0.
var age = DateTime.now().year - (n ?? 0) ;
Another solution is, just using an if checking for null followed by an else block, like:
if(n == null) {
print("Bad Year");
}
else {
var age = DateTime.now(). year - n ;
print(" ==> You are $age year old!");
}
Taking up your comment:
i added ! after n and works fine... that is the same solution?
Adding the null-assertion operator (!) to the n in DateTime.now().year - n! is not the same solution, but it is a possible solution. And as you already mentioned it compiles and work.
But be careful:
You are telling the compiler that you are sure, that n will never be null.
With your current code you will get an runtime error, when the user enters a letter or nothing. Then the parsing of that string fails and your n is null. And now you want to subtract null from the DateTime.now().year, which is again not allowed.
You can read more about Null-Safety on https://dart.dev/codelabs/null-safety .
Side note:
The following check is not correct:
if(n=="") {
print("Bad Year");
}
If an incorrect number was entered, your n is null and this is not equal to an empty string. To get your if clause work, simply use a null check. I also recommend to add a return after the output, otherwise your person gets quite old.
if(n == null) {
print("Bad Year");
return;
}

Is there any way to chain optional assignment unwrapping into if conditional in Flutter, the way it is like Swift?

In Swift, there's a simple language feature to chain unwrapping and checking for non null like this:
if let data = functionReturningNullableNumber(), data != 0 { processNum(data) }
if let data = functionReturningNullableString(), data != "" { processStr(data) }
In Flutter, currently I have to do this:
var dataNum = functionReturningNullableNumber();
if (dataNum != null && dataNum != 0) { processNum(dataNum); }
var dataStr = functionReturningNullableString();
if (dataStr != null && dataStr != "") { processStr(dataStr); }
Is it possible to create something similar to the Swift above? Especially the part where I can assign a temporary variable name that will disappear outside of the if scope, so I can reuse the variable name.
Of course I can do this:
if (functionReturningNullableNumber() != null && functionReturningNullableNumber() != 0) { process(functionReturningNullableNumber()); }
But this isn't what I'm searching for.

Checking multiple conditions for a string in C#

I want to check multiple conditions in a string in C# but it throws error saying Cannot use && for string or boolean
if ((duStart.Trim() != "" && duStart.Trim() != null) &&(duEnd.Trim() != "" && duEnd.Trim() != null))
{
//do this
}
else
//do that
The code you've given compiles fine. Here's a short but complete program - I've changed the whitespace of your line of code, but that's all:
using System;
class Test
{
static void Main()
{
string duStart = "X";
string duEnd = "X";
if ((duStart.Trim() != "" && duStart.Trim() != null) &&
(duEnd.Trim() != "" && duEnd.Trim() != null))
{
Console.WriteLine("Yes");
}
}
}
Having said that:
If you're going to use the same value (the trimmed version of duStart, for example) multiple times, there seems little point in computing it twice. I'd have used extra local variables (trimmedStart, trimmedEnd) here
Trim never returns null, so those tests are pointless.
Using string.IsNullOrWhitespace is probably a better idea here. Why bother creating strings that you're never going to use?
you can simplify the condition by writing:
if( !string.IsNullOrEmpty(duStart.Trim()) && !string.isNullOrEmpty(duEnd.Trim()) )
{
}
Check for the Null first for duStart and duEnd. Then try Trim the string. Trim cannot be applied on a null value. So, below code block should work for you.
if ((duStart != null && duStart.Trim() != "") && (duEnd != null && duEnd.Trim() != ""))
{
//do this
}
else
{
//do that
}