{"action":"created","issue":{"url":"https://api.github.com/repos/ReactiveX/RxJava/issues/3037","labels_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/3037/labels{/name}","comments_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/3037/comments","events_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/3037/events","html_url":"https://github.com/ReactiveX/RxJava/issues/3037","id":89728285,"number":3037,"title":"Observable<Void> Usage or VoidObservable","user":{"login":"NiteshKant","id":820005,"avatar_url":"https://avatars.githubusercontent.com/u/820005?v=3","gravatar_id":"","url":"https://api.github.com/users/NiteshKant","html_url":"https://github.com/NiteshKant","followers_url":"https://api.github.com/users/NiteshKant/followers","following_url":"https://api.github.com/users/NiteshKant/following{/other_user}","gists_url":"https://api.github.com/users/NiteshKant/gists{/gist_id}","starred_url":"https://api.github.com/users/NiteshKant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NiteshKant/subscriptions","organizations_url":"https://api.github.com/users/NiteshKant/orgs","repos_url":"https://api.github.com/users/NiteshKant/repos","events_url":"https://api.github.com/users/NiteshKant/events{/privacy}","received_events_url":"https://api.github.com/users/NiteshKant/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ReactiveX/RxJava/labels/Discussion","name":"Discussion","color":"5319e7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":21,"created_at":"2015-06-20T06:50:13Z","updated_at":"2015-10-16T20:14:57Z","closed_at":null,"body":"While working on [RxNetty](https://github.com/ReactiveX/RxNetty), a networking library that layers RxJava on top of netty, I have come across a common case of expressing result of an operation as an `Observable<Void>`. A typical case being the result of a `write` on a `Connection`. The API for write looks like:\r\n\r\n`public Observable<Void> write(Observable<T> msgs);`\r\n\r\nThe return value just represents the asynchronous result of the write and hence does not emit any item, so has the type as `Void`.\r\n\r\nThis works pretty well, however, it becomes awkward when we start doing a bit more complex operations over this write. eg: If I am writing a TCP client that sends a message on the connection and then reads the response from the server, I start doing things like:\r\n\r\n```java\r\nconnection.write(Observable.just(\"hello\"))\r\n                 .cast(String.class)\r\n                 .concatWith(connection.getInput())\r\n```\r\n(Actual example [here](https://github.com/ReactiveX/RxNetty/blob/0.5.x/rxnetty-examples/src/main/java/io/reactivex/netty/examples/tcp/echo/EchoClient.java#L81))\r\n\r\nIn this example, `connection.getInput()` returns an `Observable<T>` emitting items as read on the connection.\r\n\r\nand in case, I do not want to wait for write to complete, the code looks like:\r\n\r\n```java\r\nconnection.write(Observable.just(\"hello\"))\r\n                 .cast(String.class)\r\n                 .mergeWith(connection.getInput())\r\n```\r\n\r\nWhat is awkward in the above example, is the `cast(String.class)`. It is completely safe as the `write` never emits an item (`Void`) so I can merge/concat heterogeneous streams but it is just awkward.\r\n\r\nMy motivation behind creating this issue is to first see if other folks have come across the same scenario, if so, how have they handled it. Secondly, if this does sound like something worth spending time to make it better, I would like to propose some abstraction on the lines of a `VoidObservable` (for the lack of a better name) which basically provides better constructs around:\r\n\r\n- __Concat with a different type__: `write().cast().concatWith()` example above,  where it is expected to continue with another stream of a different type (`String` in the above example)\r\n- __Merge with a different type__: `write().cast().mergeWith()` example above, where it is expected to eagerly subscribe to the second `Observable` but listen only for errors from the `Observable<Void>`\r\n"},"comment":{"url":"https://api.github.com/repos/ReactiveX/RxJava/issues/comments/148822728","html_url":"https://github.com/ReactiveX/RxJava/issues/3037#issuecomment-148822728","issue_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/3037","id":148822728,"user":{"login":"ibaca","id":1042225,"avatar_url":"https://avatars.githubusercontent.com/u/1042225?v=3","gravatar_id":"","url":"https://api.github.com/users/ibaca","html_url":"https://github.com/ibaca","followers_url":"https://api.github.com/users/ibaca/followers","following_url":"https://api.github.com/users/ibaca/following{/other_user}","gists_url":"https://api.github.com/users/ibaca/gists{/gist_id}","starred_url":"https://api.github.com/users/ibaca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ibaca/subscriptions","organizations_url":"https://api.github.com/users/ibaca/orgs","repos_url":"https://api.github.com/users/ibaca/repos","events_url":"https://api.github.com/users/ibaca/events{/privacy}","received_events_url":"https://api.github.com/users/ibaca/received_events","type":"User","site_admin":false},"created_at":"2015-10-16T20:14:57Z","updated_at":"2015-10-16T20:14:57Z","body":"What do you think about this names? (I prefer not to force emptiness as commented here https://github.com/ReactiveX/RxJava/pull/3430)\r\n\r\n**then** similar to promises 'then', second merged after first completed\r\n```java\r\nconnection.write(0x1234).cast(String.class).concatWith(connection.getInput())\r\nconnection.write(0x1234).then(connection.getInput())\r\n<V> Observable<V> then(Observable<V>> v1) { return ((Observable<V>) ignoreElements()).concatWith(v1); }\r\n```\r\n**flat** as flatMap but ignore elements, so nothing to map.\r\n```java\r\nconnection.write(0x1234).cast(String.class).mergeWith(connection.getInput())\r\nconnection.write(0x1234).flat(connection.getInput())\r\n<V> Observable<V> flat(Observable<V> v1) { return ((Observable<V>) ignoreElements()).mergeWith(v1); }\r\n```\r\n**none** [as single but assert emptiness](https://github.com/ReactiveX/RxJava/pull/3430#issuecomment-148778876)\r\n\r\n*note: I think that concatWith is not working as expected in this talk because it subscribe to the first two elements (means, v1 is immediately subscribed), so you need to wrap the v1 into a defer()."}}