61502

Notification when ReactiveCommand completes

I'm trying to use ReactiveUI ReactiveCommands to switch on and off a gRPC stream that I've converted into an observable.

The code shown below works to some extent - the connect button will cause the stream to connect, and I start receiving data in the onNext handler of the subscribe. The disconnect button does also disconnect the stream via the cancellation token.

However, once the disconnect command is executed, I would also like to be notified so I can clear up some other state in the application. I understand that the onCompleted of the ReactiveCommand never gets called, because at any point it could be executed again, so my question is - how can I know when the stream has been switched off?

View

this.WhenActivated(d =>
{
    d(this.BindCommand(ViewModel, x => x.ConnectCommand, x => x.Connect));
    d(this.BindCommand(ViewModel, x => x.DisconnectCommand, x => x.Disconnect));
});


ViewModel

ConnectCommand = ReactiveCommand.CreateFromObservable(
    () => appService.ApplicationStream(request)
        .TakeUntil(DisconnectCommand));
ConnectCommand.Subscribe(
    resp => 
    { 
        _logger.Debug(resp); 
    },
    () => 
    {
        // Ideally I could do something useful here, but https://stackoverflow.com/a/26599880/57215
        _logger.Debug("Never called, ReactiveCommands never OnComplete"); 
    });

ConnectCommand.IsExecuting.Subscribe(x => _logger.Debug($"is executing: {x}"));
ConnectCommand.CanExecute.Subscribe(x => _logger.Debug($"can execute: {x}"));
ConnectCommand.ThrownExceptions.Subscribe(ex =>
    throw new Exception($"Could not get data from server: {ex}"));

DisconnectCommand = ReactiveCommand.Create(
    () => { },
    ConnectCommand.IsExecuting);


Service

public IObservable<ApplicationStreamResponse> ApplicationStream(ApplicationStreamRequest request)
{
    return Observable.Create<ApplicationStreamResponse>(async (observer, token) =>
    {
        try
        {
            using (var call = _client.ApplicationStream(request, cancellationToken: token))
            {

                while (await call.ResponseStream.MoveNext())
                {
                    if (token.IsCancellationRequested) return;
                    observer.OnNext(call.ResponseStream.Current);
                }
                observer.OnCompleted();
            }
        }
        catch (RpcException e)
        {
            if (e.Status.StatusCode == StatusCode.Cancelled)
            {
                _logger.Debug($"Application stream was disconnected: {e.Status.Detail}");
                observer.OnCompleted();
            }
            observer.OnError(e);
        }
    });
}

    

Answer1:

Subscribe to the command:

d(this.BindCommand(ViewModel, x => x.DisconnectCommand, x => x.Disconnect)); this.ViewModel.DisconnectCommand .Subscribe(_ => { /* command finished */});

Or create a bool reative property, set it to true at the end of the DisconnectCommand code, and check the value in the view.

Recommend

  • How to scroll a console command output in GVim?
  • jQuery - .always() callback firing too soon
  • Nuget pack does not recognize $version$ in dependencies
  • Stable Django-Haystack + elasticsearch setup
  • Shared Preferences data remains stored if phone is switched off or battery is taken out?
  • Sharing Redis settings across routes
  • How to clear specified format data from clipboard?
  • ValueError: Found arrays with inconsistent numbers of samples
  • Firefox extension testing and developing - I'm confused
  • Django AWS S3 Invalid certificate when using bucket name “.”
  • How do i disable a text box within an iframe
  • How to remove single character words from string with preg_replace
  • How does inheritance and polymorphism work in this situation?
  • BackgroundTransferRequest WP7
  • Deduce parent class of inherited method in C++
  • Haskell: function composition with anonymous/lambda function
  • What's the name of this finding square root algorithm?
  • C function strchr - How to calculate the position of the character?
  • How to use tag-it
  • why calling cd shell command through system() or execvp() from a child process won't work?
  • Can I programmatically choose the Android layout folder?
  • Redux Form - Not able to type anything in input
  • Insert new calendar with SyncAdapter- Calendar API Android
  • MonoTouch: How to download pdf incrementally as indicated in the Apple slides “Building Newsstand Ap
  • Installing Apache MyFaces 2 on WildFly 8.2.0
  • Content-Length header not returned from Pylons response
  • Ajax Loaded meta Tags
  • Using jQuery closest() method with class selector
  • Xamarin Forms - UWP Fonts
  • Array.prototype.includes - not transformed with babel
  • How would I use PHP exceptions to define a redirect?
  • How to extract text from Word files using C#?
  • Arrow is showed instead of the material design version hamburger icon. Why doesn't syncState in
  • Arrays break string types in Julia
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • need help with bizarre java.net.HttpURLConnection behavior
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?