App has crashed, executing CustomActivityOnCrash's UncaughtExceptionHandler
com.airbnb.epoxy.ImmutableModelException: The model was changed between being added to the controller and being bound
Controller class
class SortFilterController @Inject constructor(
private val schedulersFacade: SchedulersFacade,
private val generateMapOfCategoryFilters: GenerateMapOfCategoryFilters
) : EpoxyController() {
private val tapCountryRelay: PublishRelay<TopsProductFilter> = PublishRelay.create()
var sortFilterViewState: SortFilterViewState = SortFilterViewState()
set(value) {
field = value
requestModelBuild()
}
var sortFilterType: SortFilterType = SortFilterType.ALL
set(value) {
field = value
requestModelBuild()
}
override fun buildModels() {
sortFilterViewState.let { sortFilterViewState ->
sortFilterViewState.filterTypes?.forEach { topsProductFilter ->
when (SortFilterType.getId(topsProductFilter.attributeCode)) {
SortFilterType.COUNTRY -> {
CountryItemModel_()
.id(UUID.randomUUID().toString())
.tapCountryChipRelay(tapCountryRelay)
.countryFilter(topsProductFilter)
.listOfPreSelectedCountryFilters(sortFilterViewState.listOfCurrentlySelectedCountryItems ?: emptyList())
.addTo(this)
}
}
}
}
}
val bindTapCountryRelay: Observable<TopsProductFilter> = tapCountryRelay.hide()
}
// model class
@EpoxyModelClass(layout = R.layout.list_item_country_item)
abstract class CountryItemModel : EpoxyBaseModel() {
@EpoxyAttribute
lateinit var tapCountryChipRelay: PublishRelay<TopsProductFilter>
@EpoxyAttribute
lateinit var countryFilter: TopsProductFilter
@EpoxyAttribute
lateinit var listOfPreSelectedCountryFilters: MutableList<TopsProductFilterItem>
override fun bind(holder: EpoxyBaseViewHolder) {
with(holder.itemView) {
// snippet here
}
}
}
In the DialogFragment oncreate I setup the epoxyRecyclerView.
epoxyRecyclerView.setController(sortFilterController)
epoxyRecyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
And call the setters on the controller and request the model build
sortFilterController.sortFilterViewState = sortFilterViewState
sortFilterController.sortFilterType = SortFilterType.ALL
However, the problem is that I want to change the data that is displayed in the models with some new data. So when the user taps on a country I want to set the setter again.
private fun onTapClearAll() {
// sortFilterViewState has some new data so I want to set it again for display.
// This calling these resulted in a crash as the models epoxy attributes have changed with this new data
sortFilterController.sortFilterViewState = sortFilterViewState
sortFilterController.sortFilterType = SortFilterType.ALL
}
// Then I tried to do the same with a interceptor but again the app will crash.
private fun onTapClearAll() {
sortFilterController.addInterceptor(object : EpoxyController.Interceptor {
override fun intercept(models: MutableList<EpoxyModel<*>>) {
val countryModel = models[0] as CountryItemModel_
countryModel.listOfPreSelectedCountryFilters(sortFilterViewState.listOfCurrentlySelectedCountryItems)
}
})
sortFilterController.requestModelBuild()
}