RxJava using toList after flatMap fails as flatMap isn't complete
I have three objects (say A,B,C) and to get C I need B, and to get A, I need B. In screen I need to display a property of A together with a property of C. Even though I can get all necessary data, since I use flatMap which do not have onComplete, toList() does not get executed. Here is my code.
For every a in List I need to get c and I need to return a list of type ResultMode which includes properties of a and c.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() //Returns Flowable<List<A>>
.flatMap Flowable.fromIterable(it)
.flatMap helperMethod(it)
.toList() // Does not get executed as flatMap isnt completed
.toFlowable()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
private fun helperMethod(a:A): Flowable<ResultModel>
return mySdk
.getB(a.propertyOne!!) // Returns Single<B>
.flatMap mySdk.getC(it.property!!) // get C returns Single<C>
.map
ResultModel(name= a.name,
date = c.date.toString(),
message = it.messageId!!
)
.toFlowable()
Note: I asked a similar question earlier today but it did not require using flatmap more than once. You can view my solution to that in this link
RxJava - Mapping a result of list to another list
My Effort (Which is probably wrong)
Here is my effort of transforming first method (for second method I just remove to Flowable and return single) but it has a long way to go and I think I am in the wrong path.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle Flowable.fromIterable(it)
.map helperMethod(it)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it) // here it is single. I think it is because two maps are applied both to helperMethod itself and inside helper method to result model
android kotlin rx-java rx-java2
|
show 3 more comments
I have three objects (say A,B,C) and to get C I need B, and to get A, I need B. In screen I need to display a property of A together with a property of C. Even though I can get all necessary data, since I use flatMap which do not have onComplete, toList() does not get executed. Here is my code.
For every a in List I need to get c and I need to return a list of type ResultMode which includes properties of a and c.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() //Returns Flowable<List<A>>
.flatMap Flowable.fromIterable(it)
.flatMap helperMethod(it)
.toList() // Does not get executed as flatMap isnt completed
.toFlowable()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
private fun helperMethod(a:A): Flowable<ResultModel>
return mySdk
.getB(a.propertyOne!!) // Returns Single<B>
.flatMap mySdk.getC(it.property!!) // get C returns Single<C>
.map
ResultModel(name= a.name,
date = c.date.toString(),
message = it.messageId!!
)
.toFlowable()
Note: I asked a similar question earlier today but it did not require using flatmap more than once. You can view my solution to that in this link
RxJava - Mapping a result of list to another list
My Effort (Which is probably wrong)
Here is my effort of transforming first method (for second method I just remove to Flowable and return single) but it has a long way to go and I think I am in the wrong path.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle Flowable.fromIterable(it)
.map helperMethod(it)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it) // here it is single. I think it is because two maps are applied both to helperMethod itself and inside helper method to result model
android kotlin rx-java rx-java2
DoesmySdk.getAllA()
is infinite? or it completes immediately after posting value?
– ConstOrVar
Nov 15 '18 at 17:03
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
Yes, you are right. For infinite observablestoList()
not working because it's (operator) logic is based ononComplete()
. You are moving on the right way withEffort
. Please, note that if you don't want transformObservable
toSingle
, you can calltoList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.
– ConstOrVar
Nov 15 '18 at 18:14
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40
|
show 3 more comments
I have three objects (say A,B,C) and to get C I need B, and to get A, I need B. In screen I need to display a property of A together with a property of C. Even though I can get all necessary data, since I use flatMap which do not have onComplete, toList() does not get executed. Here is my code.
For every a in List I need to get c and I need to return a list of type ResultMode which includes properties of a and c.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() //Returns Flowable<List<A>>
.flatMap Flowable.fromIterable(it)
.flatMap helperMethod(it)
.toList() // Does not get executed as flatMap isnt completed
.toFlowable()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
private fun helperMethod(a:A): Flowable<ResultModel>
return mySdk
.getB(a.propertyOne!!) // Returns Single<B>
.flatMap mySdk.getC(it.property!!) // get C returns Single<C>
.map
ResultModel(name= a.name,
date = c.date.toString(),
message = it.messageId!!
)
.toFlowable()
Note: I asked a similar question earlier today but it did not require using flatmap more than once. You can view my solution to that in this link
RxJava - Mapping a result of list to another list
My Effort (Which is probably wrong)
Here is my effort of transforming first method (for second method I just remove to Flowable and return single) but it has a long way to go and I think I am in the wrong path.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle Flowable.fromIterable(it)
.map helperMethod(it)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it) // here it is single. I think it is because two maps are applied both to helperMethod itself and inside helper method to result model
android kotlin rx-java rx-java2
I have three objects (say A,B,C) and to get C I need B, and to get A, I need B. In screen I need to display a property of A together with a property of C. Even though I can get all necessary data, since I use flatMap which do not have onComplete, toList() does not get executed. Here is my code.
For every a in List I need to get c and I need to return a list of type ResultMode which includes properties of a and c.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() //Returns Flowable<List<A>>
.flatMap Flowable.fromIterable(it)
.flatMap helperMethod(it)
.toList() // Does not get executed as flatMap isnt completed
.toFlowable()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
private fun helperMethod(a:A): Flowable<ResultModel>
return mySdk
.getB(a.propertyOne!!) // Returns Single<B>
.flatMap mySdk.getC(it.property!!) // get C returns Single<C>
.map
ResultModel(name= a.name,
date = c.date.toString(),
message = it.messageId!!
)
.toFlowable()
Note: I asked a similar question earlier today but it did not require using flatmap more than once. You can view my solution to that in this link
RxJava - Mapping a result of list to another list
My Effort (Which is probably wrong)
Here is my effort of transforming first method (for second method I just remove to Flowable and return single) but it has a long way to go and I think I am in the wrong path.
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle Flowable.fromIterable(it)
.map helperMethod(it)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it) // here it is single. I think it is because two maps are applied both to helperMethod itself and inside helper method to result model
android kotlin rx-java rx-java2
android kotlin rx-java rx-java2
edited Nov 15 '18 at 17:08
Cem
asked Nov 15 '18 at 16:43
CemCem
486
486
DoesmySdk.getAllA()
is infinite? or it completes immediately after posting value?
– ConstOrVar
Nov 15 '18 at 17:03
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
Yes, you are right. For infinite observablestoList()
not working because it's (operator) logic is based ononComplete()
. You are moving on the right way withEffort
. Please, note that if you don't want transformObservable
toSingle
, you can calltoList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.
– ConstOrVar
Nov 15 '18 at 18:14
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40
|
show 3 more comments
DoesmySdk.getAllA()
is infinite? or it completes immediately after posting value?
– ConstOrVar
Nov 15 '18 at 17:03
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
Yes, you are right. For infinite observablestoList()
not working because it's (operator) logic is based ononComplete()
. You are moving on the right way withEffort
. Please, note that if you don't want transformObservable
toSingle
, you can calltoList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.
– ConstOrVar
Nov 15 '18 at 18:14
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40
Does
mySdk.getAllA()
is infinite? or it completes immediately after posting value?– ConstOrVar
Nov 15 '18 at 17:03
Does
mySdk.getAllA()
is infinite? or it completes immediately after posting value?– ConstOrVar
Nov 15 '18 at 17:03
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
Yes, you are right. For infinite observables
toList()
not working because it's (operator) logic is based on onComplete()
. You are moving on the right way with Effort
. Please, note that if you don't want transform Observable
to Single
, you can call toList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.– ConstOrVar
Nov 15 '18 at 18:14
Yes, you are right. For infinite observables
toList()
not working because it's (operator) logic is based on onComplete()
. You are moving on the right way with Effort
. Please, note that if you don't want transform Observable
to Single
, you can call toList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.– ConstOrVar
Nov 15 '18 at 18:14
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40
|
show 3 more comments
2 Answers
2
active
oldest
votes
There doesn't seem to be a good reason to continually deconstruct and reconstruct lists. Assuming there isn't:
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item =>
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Because the concatMapSingle()
operator knows about each item, its name can be known when it is time to construct the ResultModel
. Now, you no longer need to tear things apart so often.
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
add a comment |
Edit : I found another solution
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle
Flowable.fromIterable(it)
.flatMap a ->
mySdk.getB(a.propertyOfA!!)
.flatMap b -> chatbotSdk.getC(b.propertyOfB!!)
.map it ->
ResultModel(name = a.name,
message = it.body!!)
.toFlowable()
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Original Solution
This is my solution but I think this solution is really messy and it can be improved a lot.
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle
Flowable.fromIterable(it)
.map AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) //getB returns Single B
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
BtoCDTO(it.name,
it.b.concatMapSingle mySdk.getC(it.propertyOfB!!) ) // getC returns Single C
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. UsegetAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324132%2frxjava-using-tolist-after-flatmap-fails-as-flatmap-isnt-complete%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
There doesn't seem to be a good reason to continually deconstruct and reconstruct lists. Assuming there isn't:
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item =>
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Because the concatMapSingle()
operator knows about each item, its name can be known when it is time to construct the ResultModel
. Now, you no longer need to tear things apart so often.
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
add a comment |
There doesn't seem to be a good reason to continually deconstruct and reconstruct lists. Assuming there isn't:
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item =>
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Because the concatMapSingle()
operator knows about each item, its name can be known when it is time to construct the ResultModel
. Now, you no longer need to tear things apart so often.
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
add a comment |
There doesn't seem to be a good reason to continually deconstruct and reconstruct lists. Assuming there isn't:
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item =>
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Because the concatMapSingle()
operator knows about each item, its name can be known when it is time to construct the ResultModel
. Now, you no longer need to tear things apart so often.
There doesn't seem to be a good reason to continually deconstruct and reconstruct lists. Assuming there isn't:
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item =>
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
)
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Because the concatMapSingle()
operator knows about each item, its name can be known when it is time to construct the ResultModel
. Now, you no longer need to tear things apart so often.
answered Nov 15 '18 at 19:18
Bob DalgleishBob Dalgleish
6,25212335
6,25212335
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
add a comment |
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
Hi, I am editing your answer because of syntax errors and return type but this does not work. I dont see the difference between using flatMap and use iterable inside action and using flatMapIterableit. Please feel free to warn me if you think I edited wrong or why this method should work
– Cem
Nov 16 '18 at 5:41
add a comment |
Edit : I found another solution
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle
Flowable.fromIterable(it)
.flatMap a ->
mySdk.getB(a.propertyOfA!!)
.flatMap b -> chatbotSdk.getC(b.propertyOfB!!)
.map it ->
ResultModel(name = a.name,
message = it.body!!)
.toFlowable()
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Original Solution
This is my solution but I think this solution is really messy and it can be improved a lot.
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle
Flowable.fromIterable(it)
.map AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) //getB returns Single B
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
BtoCDTO(it.name,
it.b.concatMapSingle mySdk.getC(it.propertyOfB!!) ) // getC returns Single C
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. UsegetAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
add a comment |
Edit : I found another solution
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle
Flowable.fromIterable(it)
.flatMap a ->
mySdk.getB(a.propertyOfA!!)
.flatMap b -> chatbotSdk.getC(b.propertyOfB!!)
.map it ->
ResultModel(name = a.name,
message = it.body!!)
.toFlowable()
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Original Solution
This is my solution but I think this solution is really messy and it can be improved a lot.
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle
Flowable.fromIterable(it)
.map AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) //getB returns Single B
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
BtoCDTO(it.name,
it.b.concatMapSingle mySdk.getC(it.propertyOfB!!) ) // getC returns Single C
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. UsegetAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
add a comment |
Edit : I found another solution
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle
Flowable.fromIterable(it)
.flatMap a ->
mySdk.getB(a.propertyOfA!!)
.flatMap b -> chatbotSdk.getC(b.propertyOfB!!)
.map it ->
ResultModel(name = a.name,
message = it.body!!)
.toFlowable()
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Original Solution
This is my solution but I think this solution is really messy and it can be improved a lot.
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle
Flowable.fromIterable(it)
.map AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) //getB returns Single B
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
BtoCDTO(it.name,
it.b.concatMapSingle mySdk.getC(it.propertyOfB!!) ) // getC returns Single C
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Edit : I found another solution
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA()
.concatMapSingle
Flowable.fromIterable(it)
.flatMap a ->
mySdk.getB(a.propertyOfA!!)
.flatMap b -> chatbotSdk.getC(b.propertyOfB!!)
.map it ->
ResultModel(name = a.name,
message = it.body!!)
.toFlowable()
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
Original Solution
This is my solution but I think this solution is really messy and it can be improved a lot.
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>>
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle
Flowable.fromIterable(it)
.map AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) //getB returns Single B
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
BtoCDTO(it.name,
it.b.concatMapSingle mySdk.getC(it.propertyOfB!!) ) // getC returns Single C
.toList()
.concatMapSingle
Flowable.fromIterable(it)
.map
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
.toList()
.onErrorReturn Collections.emptyList()
.subscribeOn(Schedulers.io())
.to LiveDataReactiveStreams.fromPublisher(it)
edited Nov 16 '18 at 8:34
answered Nov 15 '18 at 18:41
CemCem
486
486
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. UsegetAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
add a comment |
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. UsegetAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
The answer from @Bob Dalgleish looks pretty good and I suppose it what you need
– ConstOrVar
Nov 15 '18 at 19:50
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
His answer has getAllA().flatMapIterableit instead of getAllA().flatMap Flowable.fromIterable(it) . Does this make any difference? That code still does not execute toList. As getAllA is infinite using toList after flatMapIterableit should also fail
– Cem
Nov 16 '18 at 5:54
Yes, you are right. But all other chain, he writes is good enough. Use
getAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
Yes, you are right. But all other chain, he writes is good enough. Use
getAllA().flatMap Flowable.fromIterable(it).flatMap mySdk.getB(item.propertyOfA!!) .flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) ) .map( ResultModel( name=item.name, message=it.body!! ) ) .toList().toObservable()
– ConstOrVar
Nov 16 '18 at 6:35
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
I could not make it work, maybe I am doing something wrong. By the way I solved the problem with a better way (compared to my old solution). Is it an ok solution?
– Cem
Nov 16 '18 at 8:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324132%2frxjava-using-tolist-after-flatmap-fails-as-flatmap-isnt-complete%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Does
mySdk.getAllA()
is infinite? or it completes immediately after posting value?– ConstOrVar
Nov 15 '18 at 17:03
It is infinite hence I cant use toList and I opted to use concatMapSingle. That is the source of my problem
– Cem
Nov 15 '18 at 17:07
Yes, you are right. For infinite observables
toList()
not working because it's (operator) logic is based ononComplete()
. You are moving on the right way withEffort
. Please, note that if you don't want transformObservable
toSingle
, you can calltoList().toObservable()
- that allow you listen not only first emission of infinite source, but listen until disposed.– ConstOrVar
Nov 15 '18 at 18:14
Hi Const I achieved my goal but my solution is really really messy and I don't think it is the right way to solve it and there can be a lot of bugs. I am posting it in 10 minutes. Can you review it?
– Cem
Nov 15 '18 at 18:27
I will try during hour
– ConstOrVar
Nov 15 '18 at 18:40