'Cannot convert value of type 'Observable<Data>' to expected argument type 'Data'
How do I cast Observable<Data> to Data? I.e getting the value of the observable.
Data.rx_subscribeData()
.map({ data -> [Model] in
return data.enumerated().map({ (index, item) in
return Model(data: item)
})
})
.bindTo(tableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
Solution 1:[1]
You do not cast an observable to a type, you subscribe to that observables events.
func observeSomeData() -> Observable<Data> {
// some rx magic
return Observable.create { observer in
let string = "Hello World"
let data = string.data(using: String.Encoding.utf8)
observer.on(.next(data))
observer.on(.completed)
return Disposables.create()
}
}
You now subscribe to this observable and respond to its events. You can do this in a number of ways, I prefer the more verbose way.
_ = observeSomeData.subscribe() { event in
switch event {
case .next(let data):
// here you have data.
case .error(let error):
// an error occurred
case .completed:
// the observable has finished sending events.
}
}
There is more information on the Getting Started documentation on the RxSwift GitHub page.
UPDATE:
I'm no expert in RxSwift but I believe I've managed to get it working.
here is the first version of the code I had in a test project.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
_ = getData().subscribe() { event in
switch event {
case .next(let data):
let str = String(data: data, encoding: String.Encoding.utf8)
print("Received string data: \(String(describing: str))")
case .completed:
print("completed")
case .error(let error):
print("error occurred: \(error)")
}
}
}
func getData() -> Observable<Data> {
return Observable.create { observer in
let data = "Hello World".data(using: String.Encoding.utf8)!
observer.on(.next(data))
observer.on(.completed)
return Disposables.create()
}
}
}
So this code just creates an observable of type Observable, which just emits a single event with some data in it. This works but does not transform the data as you wish.
The second version of the code I have..
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
_ = getData().flatMap({ (data: Data) -> Observable<String> in
return Observable.just(String(data: data, encoding: String.Encoding.utf8)!)
}).subscribe() { event in
switch event {
case .next(let str):
print("Received string data: \(String(describing: str))")
case .completed:
print("completed")
case .error(let error):
print("error occurred: \(error)")
}
}
}
func getData() -> Observable<Data> {
return Observable.create { observer in
let data = "Hello World".data(using: String.Encoding.utf8)!
observer.on(.next(data))
observer.on(.completed)
return Disposables.create()
}
}
}
So here, note the observable itself is unchanged. Now when I subscribe to the observable, I then use flatMap to transform the incoming data into an Observable of type Observable.
As I had this explained to me like this: in Rx world, .map expects you to return the same type that is passed into it, but flatMap can be used to transform the element into something else. can someone clarify this or explain in more detail?
So, to hopefully answer your question.. You can map on the observable to do transformations using flatMap and then subscribe to the new observable which will give you your transformed value.
Hope this helps
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
