nika.interisti
nika.interisti

Reputation: 198

create RxCommand with two combined streams

I have a form with two inputs: name & address and a save button.

So i've created a change and isValid commands for each

final _nameChangedCommand = RxCommand.createSync<String, String>((x) => x);
final _isNameValidCommand = RxCommand.createSync<String, bool>((x) => x != "");

final _addressChangedCommand = RxCommand.createSync<String, String>((x) => x);
final _isAddressValidCommand = RxCommand.createSync<String, bool>((x) => x != "");

I'm trying to create same for save button, where canSave = _isNameValidCommand && _isAddressValidCommand, but cant figure out the syntax.

I've created a ZipStream :

final _isNameAddressValidStream =
    new StreamZip([_isNameValidCommand, _isAddressValidCommand])
        .map((results) => results.first && results.last)
        .distinct();

final _canSaveCommand =
    RxCommand.createFromStream((_) => _isNameAddressValidStream);

but stream is never called.

Any hints?

Upvotes: 3

Views: 562

Answers (1)

Thomas
Thomas

Reputation: 9257

Yes 'combineLatest' came also to my mind. what is important with combineLatest is that it won't issue any data unless it received something on all input Streams. Best to reach that if you add a .startWith with an initial value before feeding it to the conbineLatest. Something like

final _isNameAddressValidStream =
    Observable.combineLatest2<String, String, bool>(
        _nameChangedCommand.startWith(''),
        _addressChangedCommand.startWidth(''),
        (name, address) => name != '' && address != '');

final _saveCommand = RxCommand.createSyncNoResult(
    (dataObject) => _saveToWhatever, // your actual save function 
    canExecute: _isNameAddressValidStream);
        .distinct();

So you only need two commands you can use _saveCommand for you Button's onTaphandler and use the _saveCommand.canExecute Observable to feed a StreamBuilder that created your button in activate or deactivated state.

Upvotes: 1

Related Questions