Working with Futures
in Dart, I've come across an interesting issue.
import 'dart:async';
class Egg {
String style;
Egg(this.style);
}
Future cookEggs(List<Egg> list) =>
new Future(() =>
['omelette','over easy'].forEach((_) => list.add(new Egg(_)))
);
Future cookOne(Egg egg) => new Future(() => egg = new Egg('scrambled'));
void main() {
List<Egg> eggList = new List();
Egg single;
cookEggs(eggList).whenComplete(() => eggList.forEach((_) => print(_.style));
cookOne(single).whenComplete(() => print(single.style));
}
The expected output is:
omelette
over easy
scrambled
The cookEggs
function that gets the List<Eggs>
works fine, but accessing the style
property of single
is unsuccessful and throws a NoSuchMethodError
.
I first thought that this might have something to do with pass-by-reference, but I don't see why Dart would pass a List
by reference but not an Egg
. Now I'm thinking that the discrepancy may have something to do with the assignment (=
) operator and the List.add()
method. I'm stuck in that train of thought, and I don't know how to test my hypothesis.
Any thoughts?
The program's output and stack trace is show below:
omelette
over easy
Uncaught Error: The null object does not have a getter 'style'.
NoSuchMethodError: method not found: 'style'
Receiver: null
Arguments: []
Stack Trace:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1 main.<anonymous closure> (file:///path/to/eggs.dart:20:51)
#2 _rootRun (dart:async/zone.dart:719)
#3 _RootZone.run (dart:async/zone.dart:862)
#4 _Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:540)
#5 _Future._propagateToListeners (dart:async/future_impl.dart:577)
#6 _Future._complete (dart:async/future_impl.dart:317)
#7 Future.Future.<anonymous closure> (dart:async/future.dart:118)
#8 _createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:11)
#9 _handleTimeout (dart:io/timer_impl.dart:292)
#10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:124)
Unhandled exception:
The null object does not have a getter 'style'.
NoSuchMethodError: method not found: 'style'
Receiver: null
Arguments: []
#0 _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:713)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#3 _asyncRunCallback (dart:async/schedule_microtask.dart:36)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)
null
reference is passed and, especially with these anonymous callbacks, any new variable assignments are lost with the scope. – Eggcup