How to use StreamBuilder with Observable? - dart

I'm trying to use StreamBuilder to react to multiple Streams. So, I created an Observable that I'm using to merge them:
Observable.merge([stream1, stream2, stream3])
The problem is: I don't know how to make a StreamBuilder to listen to this Observable. How should I do it?

Just declare a property in your bloc class:
Observable<T> get mergedStream => Observable.merge([stream1, stream2, stream3]);
And then use this property as source for stream property of StreamBuilder.

Related

Save last emitted value of stream in Dart

I make an app using firestore and a bottom navigation bar in Flutter. The problem is that when I switch between tabs, the build method is called everytime. The build method downloads data from firestore. Therefore, the app flickers when I switch tabs (the spinning bar is showed for a very short time). I tried to fix this by moving the firestore stream to the constructor. However, since the stream can emit before the build method, it loads forever.
A solution could been to save the last value that was emitted. I tried to fix this using the shareReplay method in Rx, but they have not implemented in RxDart yet. So, what is the best practice to implement this?
Use the shareValue operator of rxdart:
final observable = Observable(yourStream).shareValue();
Internally, this operator uses a BehaviorSubject. It will subscribe to the stream as soon as there is a single subscriber (it will only subscribe once), and unsubscribe (and dispose the subject) when there are no more subscribers.
Also, as you said, you have to create the observable in initState or a similar method (NOT the build method!). The observable should be stored in a field in the State.
In the currently accepted answer, the Observable class in RXDart has now been deprecated. Instead, you could use a BehaviorSubject but its probably best to use a ValueConnectableStream instead, like this:
final newStream = ValueConnectableStream(yourStream).autoConnect()
See the RXDart docs for more info.
Convert stream to BehaviorSubject in rxDart.
BehaviorSubject<Data> _subject = BehaviorSubject<Data>();
stream.listen((x) => _subject.add(x));
I ran the flutter app in release mode and the lag was gone, without any modifications.
You could have a look at BehaviorSubject in rxdart. According to the docs
The latest item that has been added to the subject will be sent to any new listeners of the subject.

vue.js prop array/object vs literal

Props in vue.js are one way binding, by the way,in the documentation :
https://v2.vuejs.org/v2/guide/components.html#One-Way-Data-Flow
"Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child will affect parent state."
So i want to know, the prop.sync is it only for "litteral" (ie; string, number,date) or I must use it also with object/array ?
I already use object WITHOUT sync and all work very well, but i am fear it is not the good solution for do "vue.js" way ?
SO my question is : can i use object/array in prop,without sync, with no problem ?
In some cases, we may need “two-way binding” for a prop. Unfortunately, true two-way binding can create maintenance issues, because child components can mutate the parent without the source of that mutation being obvious in both the parent and the child.
That’s why instead, we recommend emitting events in the pattern of update:myPropName. For example, in a hypothetical component with a title prop, we could communicate the intent of assigning a new value with:
this.$emit('update:title', newTitle)
You'll get errors if you mutate a prop directly in a child component. So in that sense, no it's not safe. The reason being is the parent will override anything the child sets.
Yes you can use objects and arrays as prop values. One difference, however, is when providing a default value for props of type object or array, you must define a factory function to return the default value.
The, main difference is the sync modifier is syntactic sugar that expands to a v-on listener. The child component emits events back the parent when a value changes, allowing the parent to update accordingly.
The child component must explicitly emit the event.
// example from docs
this.$emit('update:foo', newValue)

Creating a listener on a list for changes

I have a dart object which contains a list. Simply put:
class Test extends PolymerElement{
List list = [];
addTask(item){
list.add(item);
}
}
and I wanted to implement a listener on that list in another object:
class listenerClass extends PolymerElement {
Test get _data => $['Object'];
}
So the object is retrieved from the dom withthe getter.
Is there a way to observe a change in the parent? I tried the following:
#Observe("_data.list")
dataListChanged(_,__){
var item = _data.list.last;
//do magic with item.
}
I have the underscore because it is private and isnt exposed to Dom or anything... but the list itself isnt a property so it doesnt notify or anything.
I was hoping there was a way to do some sort of listener for it though.
My desired endstate is that I want to fire a function in the parent whenever an item is added to the list, with only the reference to the child object as defined above. Even though this _data is populated by way of Polymer, Since this isnt touching properties at all, the answer may likely just be Pure dart.
This is not how polymer works. Polymer framework has no way to know you have defined a getter in your class and emit the right notification.
You should add notify to the list property of Test and bind that to a property in listenerClass. Then observe that variable.
But probably you will have better luck with ObservableList and using autonotify for a simpler way to use observability with polymer-dart projects.

Is there an "observable" set or list in Dart?

I'd like to generate a stream of events from a common Set<T> object in dart so that I am informed whenever any T is added or removed. Is there anything like that already available in the core dart libraries or one of its packages?
There are observable list and map in https://pub.dartlang.org/packages/observe.

Dart initializer list and access of recently filled instance variable

I am trying to initialize some event stream in a class. I want that stream to be final, but controlled by StreamController. I have tried following code:
import "dart:async";
class Dog {
final StreamController _onBarkController;
final Stream onBark;
Dog() :
_onBarkController = new StreamController(),
onBark = _onBarkController.stream;
}
But this code is illegal, because the access (even implicit) to this is forbidden in the initializer list.
Is there any way how to achieve this?
There isn't a great way to solve the general problem of needing to destructure some object into multiple final fields, which is basically what you're attempting here. But the good news is that usually you don't really need to. The two approaches I would recommend are factory constructors and not keeping derived state.
Factory constructors are great because you can perform arbitrary computation to create your arguments before calling the real constructor, which can usually only have an initializer list. In this case you can have a factory constructor create the StreamController and pass it and the stream to a private constructor.
Even better for you though, would be to not store the Stream in a field because you can get to it via the controller. I do this all the time with streams:
class Dog {
final StreamController _onBarkController = new StreamController();
Stream get onBark => _onBarkController.stream;
}
onBark is really a value derived from _onBarkController, so there's no need to store it.

Resources