I have a method that returns a signal of signal and I have to use flattenMap
to extract the value wrapped in the signal. After that only can I use subscribeNext:complete: to get the value.
The code looks like the follows:
- (RACSignal *)publicSignal {
return [[self privateSignal] map:^id(NSString *code) {
return [self chainingSignalUsingCode:code];
}];
};
[[[obj publicSignal] flattenMap:^id(id value) {
return value;
}] subscribeNext:^(NSString *someValue) {
// extract the value;
} completed:^{
// something to do..
}];
Is there any way to eliminate the flattenMap
code so that I can directly subscribe to the publicSignal
?
Thanks in advance.
Well, you could just do the flattenMap
inside publicSignal
...
- (RACSignal *)publicSignal {
return [[[self privateSignal] map:^id(NSString *code) {
return [self chainingSignalUsingCode:code];
}] flattenMap:^(id value) {
return value;
}];
}
[[obj publicSignal] subscribeNext:^(NSString *someValue) {
// extract the value;
} completed:^{
// something to do..
}];
But then why are we map
ping and then immediately flattenMap
ping? We can just say:
- (RACSignal *)publicSignal {
return [[self privateSignal] flattenMap:^(NSString *code) {
return [self chainingSignalUsingCode:code];
}];
}
[[obj publicSignal] subscribeNext: ...
To get the same effect.
Bear in mind that flattenMap
isn't really "extracting the value in the signal." It's extracting all the values from all the signals. When privateSignal
sends new signals, publicSignal
is going to next for every value that every signal sends -- it's basically going to remember all past signals that privateSignal
sends and forward all of their nexts through. If this is what you want, then great, it works. But if you only want to "unwrap" the latest signal, use switchToLatest
instead of flattenMap
.
If you don't want to modify publicSignal
, and you want it to be a signal of signals, you can use the simpler flatten
method and subscribe to that:
[[[obj publicSignal] flatten] subscribeNext: ...
Since flattenMap
without doing anything is equivalent to flatten
(in fact flatten
is implemented as a flattenMap
that just returns its value). Or, if you only want to subscribe to nexts from the latest signal it sends:
[[[obj publicSignal] switchToLatest] subscribeNext: ...
But as long as it's a signal of signals, you need to do some operation to "unwrap" it. there's no helper flattenAndThenSubscribe
method -- which is good. You can get the effect you want through composition of simple primitives.