_thinkdigitalOP•

I'm surprised I couldn't find a previous ticket on this.

1
315iezam•

In your use case example, what's wrong with not using the ??? If null is a valid value, then let it be a valid value and treat it as such.

1
_thinkdigitalOP•

Because when you use copyWith and don't set a parameter because you're not trying to change that value, it gets set to null.

for example given the copyWith function definition is as follows:

MapState copyWith({p1, p2}){...}

if you call state.copyWith(p2: someVal), then p1 is null and is told to grab its existing value.

Example 2:bool someBool = null;state.copyWith(p1: someBool, p2: someVal)

This will return the same result as Example 1, because both times, the variable is null. There's no way to set a variable to null with a function like this.What I ended up doing was writing a `setAsNull` function:

 MapState setAsNull({
    bool activeTopCategory = false,
    bool activeCategory = false,
  }) {
    return MapState(
      activeTopCategory: activeTopCategory ? null : this.activeTopCategory,
      activeCategory: activeCategory ? null : this.activeCategory,
      topCategories: topCategories,
      categories: categories,
      subCategories: subCategories,
      isCardOpen: isCardOpen,
    );
  }
0
315iezam•

Then maybe a generic copyWith method isn't the way to go for how you're using the object.

I'm partially against adding something like undefined because most languages are moving away from null-like values being a given, even Dart is going NNDB.

Going back to the example, it could be done with a copy and using setters which would look something like

final instanceB = instanceA.copy()
                    ..field1 = null
                    ..field2 = 5;

Where copy creates a new instance of the object with the exact same values (leaving out deep copying for now).

EDIT: Was typing the above on my phone so it was a little uncomfortable.

The better solution in my opinion is to have a rich model with methods that perform exactly what you want, as opposed to generic ones like copyWith and copy from my example. If the object was a model for a shipment order, possible methods could be

class Order {
  // fields

  // implementation omitted
  void addItem(Item i);
  void approve(String by);
  void unapprove();
}

It's a bit of a contrived example but I don't have a better domain model in mind right now. For Order.items, it should never be null, whereas the approval fields can be, and they are valid values. And rather than doing orderInstance.copyWith(approvedBy: null, approvedOn: null) to reverse the approval, it can just be orderInstance.unapprove(). Users of the object doesn't need to know which fields need to be set/unset, they would know that the order can be approved and then reversed. If you want to create a new instance for every operation, change the void return type to Order.

3
_thinkdigitalOP•

Thanks. I saw a library that generates code like this. However this doesn't work when working with immutable objects since you can't have setters. I've been working with inmutables for a while now and I feel they're safer

1
315iezam•

If you're into generated code, could look into built_value. They're able to handle updates to the immutable values through a rebuild method. Haven't looked into whether that then accepts null values by default.

2
cybergatuno•

Undefined is a boulder we have carry everywhere. Just like null.

We'll soon get Non-Nullable-By-Default, I don't wanna wait for Non-Undefined-By-Default.

As someone commented on the request, Union Types are the way to go!

1
_thinkdigitalOP•

Ok, how would that fit the use case?

1