1

I'm trying to create a function that can dynamically set the properties on an object like so:

void main() {
  final obj = Item();

  obj.update(5);

  print(obj.xVal);
}

class ObjectBase {
  void _setData(current, newValue) {
    current = newValue;
    print(current);
  }
}

class Item extends ObjectBase {
  int _x;

  int get xVal => _x;

  update(x) {
    _setData(_x, x);
  }
}

The print statement in _setData works fine, but it doesn't actually appear to change _x, even if it has been passed through. I expected that changing the reference here would update it everywhere.

So why isn't this working and is there a fix?

You can assume that I do have good reason to be calling _setData inside update rather than just implementing the functionality in update.

Update:

A real life example of what i'm trying to achieve

class ViewModel extends ChangeNotifier {
  void _setDataFromDependency(current, newValue) {
    if (!deepDynamicEquality(current, newValue)) {
      current = newValue;
      notifyListeners();
    }
  }
}

class ListScreenViewModel extends ViewModel {
  int _localCount = 0;
  List<int> _globalList;

  ListScreenViewModel();

  List<int> get globalList => _globalList;
  int get localCount => _localCount;

  incrementLocal() {
    _localCount++;
    notifyListeners();
  }

  void update(ListStore listStore) {
    _setDataFromDependency(_globalList, listStore.globalList);
    // if (!deepDynamicEquality(_globalList, listStore.globalList)) {
    //   _globalList = listStore.globalList;
    //   notifyListeners();
    // }
  }
}
HJo
  • 1,902
  • 1
  • 19
  • 30
  • 1
    Does this answer your question? [Is there a way to pass a primitive parameter by reference in Dart?](https://stackoverflow.com/questions/18258267/is-there-a-way-to-pass-a-primitive-parameter-by-reference-in-dart) – julemand101 Jun 13 '20 at 13:11
  • Don't think so. My code doesn't work wether the value is a primitive or an object – HJo Jun 13 '20 at 13:17
  • Well take a look at `_setData(_x, x);`. You are expecting that `_x` can be updated when it has been given as parameter which is not possible. This was the reason why I linked to the other question since you are expecting pass by reference. – julemand101 Jun 13 '20 at 13:19
  • So you can't pass references in functions? – HJo Jun 13 '20 at 13:26
  • 3
    Not possible in Dart. If you are sending a reference to an object as a parameter the reference (pointer) are copied but you can still change the state of the object which the reference are pointing at (e.g. if you are sending a reference to a list you can add elements to the list but you cannot change the reference to point to another list object). – julemand101 Jun 13 '20 at 13:27
  • Ok, thanks for explaining this, although I still don't think I fully understand that. Can you think of a way to fix my code? – HJo Jun 13 '20 at 13:35
  • See the answer from dev-aentgs. – julemand101 Jun 13 '20 at 13:43
  • Have updated my question with a real life example, dev-aentgs solution can't work for me – HJo Jun 13 '20 at 13:53

1 Answers1

1

An oversimplified workaround is to return the value from _setData . @julemand101 has already answered limitations.

class ObjectBase {
  int _setData(current, newValue) {
    current = newValue;
    print('current: $current');
    return current;
  }
}

class Item extends ObjectBase {
  int _x;

  int get xVal => _x;

  update(x) {
    _x = _setData(_x, x);
  }
}
dev-aentgs
  • 1,218
  • 2
  • 9
  • 17
  • 1
    I thought of that but it presents its own set of problems. I've updated my answer with a real life example. With what I'm trying to achieve, I only want to update the data if the current & newValue are different, and to notifyListeners only in the situation that it's different. I can just do what's commented out, but I was hoping I would be able to do away with the boilerplate – HJo Jun 13 '20 at 13:48
  • Understood and its a good use-case. In Flutter widget lifecycle methods, there is a `didUpdateWidget` method. – dev-aentgs Jun 13 '20 at 13:51
  • This exists outside of the widget tree though – HJo Jun 13 '20 at 13:55
  • @HamishJohnson i dont have an answer yet to this question, [equatable package](https://pub.dev/packages/equatable) might help reduce some of the change comparison code. – dev-aentgs Jun 13 '20 at 14:22