Reputation: 5
I am new to both RxSwift and RxCocoa.
I have a working REST service on local which returns a Movie object for given "id".
On my storyboard there is a tableView (UITableView) which has custom cells (MovieCell). Each movie cell has a UILabel named "nameTextLabel". I also have a textField to get requested movie.id from user.
I am trying to show movie.title on each row of my tableView.
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet var textField: UITextField!
@IBOutlet var tableView: UITableView!
let bag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
configureReactiveBinding()
}
private func configureReactiveBinding() {
textField.rx.text.asObservable()
.map { ($0 == "" ? "15" : $0!).lowercased() }
.map { GetMovieByIdRequest(id: $0) }
.flatMap { request -> Observable<Movie> in
return ServiceManager.instance.send(apiRequest: request)
}
.debug("movie")
// output:
//2018-10-17 16:13:49.320: movie -> subscribed
//2018-10-17 16:13:49.401: movie -> Event next(MovieAdvisor.Movie)
//2018-10-17 16:13:52.021: movie -> Event next(MovieAdvisor.Movie)
.toArray()
.debug("tableView")
// output:
//2018-10-17 16:13:49.318: tableView -> subscribed
.bind(to: tableView.rx.items(cellIdentifier: "movie_cell", cellType:MovieCell.self)) { index, model, cell in
cell.nameTextLabel.text = model.title
}
.disposed(by: bag)
}
}
Each time textLabel is changed the new movie.id is printed, but tableView doesn't show any data-not even with initial value (when textField is "").
Any idea how can i fix this?
After adding debug() lines, i figured that tableView is subscribed just once and no next events triggered tableView. What should i do? Code is uploaded on GitHub github
Upvotes: 0
Views: 581
Reputation: 4077
Try replacing
`a.subscribe(onNext: {movie in
print(movie.title)
})
.disposed(by: bag)
with .observeOn(MainScheduler.instance)
and see whether it does the trick.
Perhaps move .toArray()
to directly after ServiceManager.instance.send(apiRequest: request)
.
Also you can add *.debug("my custom message")*
after every RxSwift operator to see whether it is getting executed.
BTW I would recommend using RxDataSources framework for this, not bare RxCocoa.
Upvotes: 1
Reputation: 33967
The problem is your toArray()
operator. That operator waits until the sequence completes and then emits the entire sequence as a single array. Your sequence doesn't complete until after you have exited the view controller.
Replace that with .map { [$0] }
instead and the movie will show. You should ask yourself though why your endpoint is only returning one movie instead of an array of movies.
Upvotes: 2