Question

I have a situation where I'm expecting a single value from a Stream, but because it's one provided by the browser I can't rely on simply calling streamSub.single. Currently, I'm creating an explicit StreamController so that I can easily generate a Future from it while guaranteeing that it will only get a single response. However, that ends up being a lot more overhead than I was expecting to have to set up, making me think I'm missing something. The current code follows:

StreamController<String> streamCtrlr = new StreamController<String>();
var popup = window.open(targetUrl, "Auth Window"); 
//The popup above will call window.opener.postMessage, so listen for messages
StreamSubscription sub = window.onMessage.listen(null);
sub.onData((Event){
  /* Logic goes here */
  sub.cancel();
  popup.close();
  streamCtrlr.add(Event.data);
  streamCtrlr.close();
});  
return streamCtrlr.stream.single;

How can this be re-written so that the intermediary StreamController isn't required?

Was it helpful?

Solution

Why can't you rely on calling streamSub.single? Is it because there might be more than one message?

Your example code picks the first event in all cases, so to get the same behavior, you can use window.onMessage.first instead of window.onMessage.single. It will still cause an error if there is no first event (but I don't think that can happen with DOM event handlers - they never send a done event), and otherwise it will give a future that is completed with the first event.

You also want to extract the event data, so you will probably want:

return window.onMessage.first.then((event) {
  /* Logic goes here */
  popup.close();
  return event.data;
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top