I am trying to modify some data from API. I have successfully implemented callbacks inside a nested recyclerview. But my selector doesn’t work now. Why is that and how do I fix it?
Below are the adapter classes.
Survey Container Adapter
<code>class SurveyContainerAdapter(
private val surveyList: ArrayList<DataSurvey>,
private val context: Context,
) :
RecyclerView.Adapter<SurveyContainerAdapter.SurveyContainerViewHolder>() {
private var onItemClickCallback: OnItemClickCallback? = null
inner class SurveyContainerViewHolder(val binding: SurveyContainerLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: DataSurvey, position: Int) {
binding.tvSurveyTitle.text = "${surveyData.name} (${position + 1}/$itemCount)"
binding.ivCloseSurvey.setOnClickListener {
onItemClickCallback?.onItemClicked(surveyData, position)
}
if (surveyData.assets.isNotEmpty()) {
binding.ivCloseSurvey.visibility = View.GONE
}
binding.rvSurveyItem.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
val adapterItem = SurveyItemAdapter(surveyData.items)
adapterItem.setOnValueCallback(object : SurveyItemAdapter.SurveyItemListener{
override fun onValueChanged(surveyId: String, itemId: String, newValue: Any?) {
onItemClickCallback?.onValueClicked(surveyId, itemId, newValue)
}
})
binding.rvSurveyItem.adapter = adapterItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyContainerViewHolder {
val view =
SurveyContainerLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyContainerViewHolder(view)
}
override fun getItemCount(): Int = surveyList.size
interface OnItemClickCallback {
fun onItemClicked(data: DataSurvey, position: Int)
fun onValueClicked(surveyId: String, itemId: String, newValue: Any?)
}
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
this.onItemClickCallback = onItemClickCallback
}
override fun onBindViewHolder(holder: SurveyContainerViewHolder, position: Int) {
holder.bind(surveyList[position], position)
}
}
</code>
<code>class SurveyContainerAdapter(
private val surveyList: ArrayList<DataSurvey>,
private val context: Context,
) :
RecyclerView.Adapter<SurveyContainerAdapter.SurveyContainerViewHolder>() {
private var onItemClickCallback: OnItemClickCallback? = null
inner class SurveyContainerViewHolder(val binding: SurveyContainerLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: DataSurvey, position: Int) {
binding.tvSurveyTitle.text = "${surveyData.name} (${position + 1}/$itemCount)"
binding.ivCloseSurvey.setOnClickListener {
onItemClickCallback?.onItemClicked(surveyData, position)
}
if (surveyData.assets.isNotEmpty()) {
binding.ivCloseSurvey.visibility = View.GONE
}
binding.rvSurveyItem.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
val adapterItem = SurveyItemAdapter(surveyData.items)
adapterItem.setOnValueCallback(object : SurveyItemAdapter.SurveyItemListener{
override fun onValueChanged(surveyId: String, itemId: String, newValue: Any?) {
onItemClickCallback?.onValueClicked(surveyId, itemId, newValue)
}
})
binding.rvSurveyItem.adapter = adapterItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyContainerViewHolder {
val view =
SurveyContainerLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyContainerViewHolder(view)
}
override fun getItemCount(): Int = surveyList.size
interface OnItemClickCallback {
fun onItemClicked(data: DataSurvey, position: Int)
fun onValueClicked(surveyId: String, itemId: String, newValue: Any?)
}
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
this.onItemClickCallback = onItemClickCallback
}
override fun onBindViewHolder(holder: SurveyContainerViewHolder, position: Int) {
holder.bind(surveyList[position], position)
}
}
</code>
class SurveyContainerAdapter(
private val surveyList: ArrayList<DataSurvey>,
private val context: Context,
) :
RecyclerView.Adapter<SurveyContainerAdapter.SurveyContainerViewHolder>() {
private var onItemClickCallback: OnItemClickCallback? = null
inner class SurveyContainerViewHolder(val binding: SurveyContainerLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: DataSurvey, position: Int) {
binding.tvSurveyTitle.text = "${surveyData.name} (${position + 1}/$itemCount)"
binding.ivCloseSurvey.setOnClickListener {
onItemClickCallback?.onItemClicked(surveyData, position)
}
if (surveyData.assets.isNotEmpty()) {
binding.ivCloseSurvey.visibility = View.GONE
}
binding.rvSurveyItem.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
val adapterItem = SurveyItemAdapter(surveyData.items)
adapterItem.setOnValueCallback(object : SurveyItemAdapter.SurveyItemListener{
override fun onValueChanged(surveyId: String, itemId: String, newValue: Any?) {
onItemClickCallback?.onValueClicked(surveyId, itemId, newValue)
}
})
binding.rvSurveyItem.adapter = adapterItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyContainerViewHolder {
val view =
SurveyContainerLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyContainerViewHolder(view)
}
override fun getItemCount(): Int = surveyList.size
interface OnItemClickCallback {
fun onItemClicked(data: DataSurvey, position: Int)
fun onValueClicked(surveyId: String, itemId: String, newValue: Any?)
}
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
this.onItemClickCallback = onItemClickCallback
}
override fun onBindViewHolder(holder: SurveyContainerViewHolder, position: Int) {
holder.bind(surveyList[position], position)
}
}
Survey Item Adapter
<code>package com.envisions.people.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.envisions.people.R
import com.envisions.people.api.responses.SurveyItem
import com.envisions.people.databinding.SurveyItemLayoutBinding
class SurveyItemAdapter(
private val surveyItemList: List<SurveyItem>
) :
RecyclerView.Adapter<SurveyItemAdapter.SurveyItemViewHolder>() {
private var surveyItemListener : SurveyItemListener? = null
inner class SurveyItemViewHolder(private val binding: SurveyItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: SurveyItem, position: Int) {
binding.tvSurveyItemTitle.text = "${position + 1}. ${surveyData.name}"
if (position == itemCount - 1) {
binding.surveyItemSeparator.visibility = View.GONE
}
binding.cbConfirmSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbCancelSurveyItem.isChecked = false
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel)
} else {
buttonView.isChecked = false
binding.cbCancelSurveyItem.isChecked = true
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel_red)
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, isChecked)
// Log.e("value on cbConfirm", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
binding.cbCancelSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbConfirmSurveyItem.isChecked = false
} else {
buttonView.isChecked = false
binding.cbConfirmSurveyItem.isChecked = true
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, !isChecked)
//
// Log.e("value on cbCancel", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyItemViewHolder {
val view =
SurveyItemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyItemViewHolder(view)
}
override fun getItemCount(): Int = surveyItemList.size
override fun onBindViewHolder(holder: SurveyItemViewHolder, position: Int) {
holder.bind(surveyItemList[position], position)
}
fun setOnValueCallback(onValueClickCallback: SurveyItemListener) {
this.surveyItemListener = onValueClickCallback
}
interface SurveyItemListener {
fun onValueChanged(surveyId: String, itemId: String, newValue: Any?)
}
}
</code>
<code>package com.envisions.people.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.envisions.people.R
import com.envisions.people.api.responses.SurveyItem
import com.envisions.people.databinding.SurveyItemLayoutBinding
class SurveyItemAdapter(
private val surveyItemList: List<SurveyItem>
) :
RecyclerView.Adapter<SurveyItemAdapter.SurveyItemViewHolder>() {
private var surveyItemListener : SurveyItemListener? = null
inner class SurveyItemViewHolder(private val binding: SurveyItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: SurveyItem, position: Int) {
binding.tvSurveyItemTitle.text = "${position + 1}. ${surveyData.name}"
if (position == itemCount - 1) {
binding.surveyItemSeparator.visibility = View.GONE
}
binding.cbConfirmSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbCancelSurveyItem.isChecked = false
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel)
} else {
buttonView.isChecked = false
binding.cbCancelSurveyItem.isChecked = true
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel_red)
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, isChecked)
// Log.e("value on cbConfirm", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
binding.cbCancelSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbConfirmSurveyItem.isChecked = false
} else {
buttonView.isChecked = false
binding.cbConfirmSurveyItem.isChecked = true
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, !isChecked)
//
// Log.e("value on cbCancel", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyItemViewHolder {
val view =
SurveyItemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyItemViewHolder(view)
}
override fun getItemCount(): Int = surveyItemList.size
override fun onBindViewHolder(holder: SurveyItemViewHolder, position: Int) {
holder.bind(surveyItemList[position], position)
}
fun setOnValueCallback(onValueClickCallback: SurveyItemListener) {
this.surveyItemListener = onValueClickCallback
}
interface SurveyItemListener {
fun onValueChanged(surveyId: String, itemId: String, newValue: Any?)
}
}
</code>
package com.envisions.people.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.envisions.people.R
import com.envisions.people.api.responses.SurveyItem
import com.envisions.people.databinding.SurveyItemLayoutBinding
class SurveyItemAdapter(
private val surveyItemList: List<SurveyItem>
) :
RecyclerView.Adapter<SurveyItemAdapter.SurveyItemViewHolder>() {
private var surveyItemListener : SurveyItemListener? = null
inner class SurveyItemViewHolder(private val binding: SurveyItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(surveyData: SurveyItem, position: Int) {
binding.tvSurveyItemTitle.text = "${position + 1}. ${surveyData.name}"
if (position == itemCount - 1) {
binding.surveyItemSeparator.visibility = View.GONE
}
binding.cbConfirmSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbCancelSurveyItem.isChecked = false
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel)
} else {
buttonView.isChecked = false
binding.cbCancelSurveyItem.isChecked = true
// binding.cbCancelSurveyItem.setBackgroundResource(R.drawable.ic_outline_cancel_red)
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, isChecked)
// Log.e("value on cbConfirm", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
binding.cbCancelSurveyItem.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.isChecked = true
binding.cbConfirmSurveyItem.isChecked = false
} else {
buttonView.isChecked = false
binding.cbConfirmSurveyItem.isChecked = true
}
surveyItemListener?.onValueChanged(surveyData.surveyId, surveyData.id, !isChecked)
//
// Log.e("value on cbCancel", "value : ${surveyData.valueItem}")
// Log.e("value survey Item id", "value : ${surveyData.surveyId}")
// Log.e("value survey id", "value : ${surveyData.id}")
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyItemViewHolder {
val view =
SurveyItemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyItemViewHolder(view)
}
override fun getItemCount(): Int = surveyItemList.size
override fun onBindViewHolder(holder: SurveyItemViewHolder, position: Int) {
holder.bind(surveyItemList[position], position)
}
fun setOnValueCallback(onValueClickCallback: SurveyItemListener) {
this.surveyItemListener = onValueClickCallback
}
interface SurveyItemListener {
fun onValueChanged(surveyId: String, itemId: String, newValue: Any?)
}
}
While below is my view model class.
<code>package com.envisions.people.viewmodels
import android.location.Location
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.envisions.people.api.responses.DataArea
import com.envisions.people.api.responses.DataAssetItem
import com.envisions.people.api.responses.DataLocationItem
import com.envisions.people.api.responses.DataSurvey
import com.envisions.people.data.models.ResultState
import com.envisions.people.data.repository.AreaRepository
import com.envisions.people.data.repository.AssetRepository
import com.envisions.people.data.repository.InspectionRepository
import com.envisions.people.data.repository.LocationRepository
import kotlinx.coroutines.launch
import java.io.File
class CheckInViewModel(
private val locationRepository: LocationRepository?,
private val inspectionRepository: InspectionRepository?,
private val areaRepository: AreaRepository?,
private val assetRepository: AssetRepository?
) : ViewModel() {
var nearestLocation: DataLocationItem? = null
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
private var _error = MutableLiveData<String>()
var errorResponse: LiveData<String> = _error
val surveyItem = MutableLiveData<ArrayList<DataSurvey>>()
private val _areaList = MutableLiveData<ArrayList<DataArea?>?>()
val areaList: LiveData<ArrayList<DataArea?>?> = _areaList
private val _assetList = MutableLiveData<ArrayList<DataAssetItem>>()
val assetList: LiveData<ArrayList<DataAssetItem>> = _assetList
val allAssetsLoaded = MutableLiveData<Boolean>()
// LiveData for etCheckInNotes
val etCheckInNotesLiveData: MutableLiveData<String> = MutableLiveData()
// Combined LiveData for etCheckInNotes and surveyItem
val combinedLiveData: MediatorLiveData<CheckInData> = MediatorLiveData()
init {
combinedLiveData.addSource(surveyItem) { surveyItem ->
val checkInData = CheckInData(etCheckInNotesLiveData.value, surveyItem)
combinedLiveData.value = checkInData
}
combinedLiveData.addSource(etCheckInNotesLiveData) { notes ->
val checkInData = CheckInData(notes, surveyItem.value ?: arrayListOf())
combinedLiveData.value = checkInData
}
}
data class CheckInData(val notes: String?, val surveyItems: ArrayList<DataSurvey>)
fun setLocationViewModel(token: String, currentLat: Double, currentLon: Double) {
allAssetsLoaded.value = false
Log.e("CheckInViewModel", "latitude : $currentLat")
Log.e("CheckInViewModel", "latitude : $currentLon")
viewModelScope.launch {
locationRepository?.setLocation(token)
?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val locationDataList = result.data.data.toList()
// Access specific location data from locationResponse object
Log.e("CheckInViewModel", locationDataList.toString())
val nearestLocationCheck =
calculateNearestDistance(locationDataList, currentLat, currentLon)
Log.e(
"CheckInViewModel",
"Nearest Location : ${nearestLocationCheck.toString()}"
)
nearestLocation = nearestLocationCheck
getArea(token, nearestLocation?.id.orEmpty())
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_isLoading.value = false
}
}
}
}
}
fun getArea(token: String, locationId: String) {
var completedAssetCalls = 0
viewModelScope.launch {
areaRepository?.getArea(token, locationId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAreaList = _areaList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAreaList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_areaList.value =
currentAreaList // Update the MutableLiveData with the new list
// for (item in result.data.data ?: arrayListOf()) {
// Log.e(TAG, "result.data.data ${result.data.data}")
// _areaList.value?.add(item)
// }
for (area in _areaList.value ?: arrayListOf()) {
getAsset(token, area?.id.orEmpty(), object : FetchCallback {
override fun onDataLoaded() {
completedAssetCalls++
if (completedAssetCalls == _areaList.value?.size) {
allAssetsLoaded.value = true
_isLoading.postValue(false)
}
}
})
}
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
fun getAsset(token: String, areaId: String, fetchCallback: FetchCallback) {
viewModelScope.launch {
assetRepository?.getAsset(token, areaId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAssetList = _assetList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAssetList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_assetList.value =
currentAssetList // Update the MutableLiveData with the new list
//
// for (item in result.data.data?: arrayListOf()) {
// _assetList.value?.add(item)
// }
fetchCallback.onDataLoaded()
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
private fun calculateNearestDistance(
listLocation: List<DataLocationItem>?,
currentLat: Double,
currentLon: Double
): DataLocationItem? {
var nearestLocationItem: DataLocationItem? = null
var nearestDistance = Float.MAX_VALUE
for (itemLocation in listLocation ?: arrayListOf()) {
val result = FloatArray(1)
val (latitudeStr, longitudeStr) = itemLocation.coordinate.split(", ")
Location.distanceBetween(
currentLat,
currentLon,
latitudeStr.toDouble(),
longitudeStr.toDouble(),
result
)
val distance = result[0]
Log.e("CheckInViewModel", "Distance : ${distance.toInt()}, Item : $itemLocation")
if (distance < nearestDistance) {
nearestDistance = distance
nearestLocationItem = itemLocation
}
}
Log.e(
"CheckInViewModel",
"Nearest Distance : ${nearestDistance.toInt()}, Nearest Item : $nearestLocationItem"
)
if (nearestDistance.toInt() > (nearestLocationItem?.radius?.toInt()
?: 500)
) nearestLocationItem = null
return nearestLocationItem
}
fun postCheckIn(
token: String,
notes: String,
locationId: String,
assetId: ArrayList<DataAssetItem>,
fileList: ArrayList<File>,
surveyList: ArrayList<DataSurvey>
) =
inspectionRepository?.postInspection(
token,
notes,
locationId,
assetId,
fileList,
surveyList
)
fun getSurveyGeneral(token: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, null)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
}
surveyItem.postValue(listSurvey as ArrayList<DataSurvey>?)
val arrayTest = ArrayList<Any?>()
surveyItem.value?.forEach { data ->
data.items.forEach { item ->
Log.e(TAG, "item: $item")
arrayTest.add(item.valueItem)
Log.e(TAG, "arraytest : $arrayTest")
}
}
}
}
}
}
}
fun getSurveyAsset(token: String, assetId: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, assetId)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
} as ArrayList<DataSurvey>
val updatedList = ArrayList<DataSurvey>()
surveyItem.value?.forEach { dataSurvey ->
updatedList.add(dataSurvey)
}
// Now, iterate through listSurvey and add elements with unique names
listSurvey.forEach { newSurveyGet ->
val isNew =
updatedList.none { existingSurvey -> existingSurvey.name == newSurveyGet.name }
if (isNew) {
updatedList.add(newSurveyGet)
}
}
surveyItem.postValue(updatedList)
Log.e(TAG, "surveyItem = ${surveyItem.value}")
}
}
}
}
}
fun updateSurveyItemValueItem(surveyId: String, itemId: String, newValue: Any?) {
val updatedList = surveyItem.value?.map { survey ->
if (survey.id == surveyId) {
survey.copy(
items = survey.items.map { item ->
if (item.id == itemId) {
item.copy(valueItem = newValue)
} else {
item
}
}
)
} else {
survey
}
}?.toMutableList()
updatedList?.let { surveyItem.value = it as ArrayList<DataSurvey> }
}
interface FetchCallback {
fun onDataLoaded()
}
companion object {
private const val TAG = "CHECKINVIEWMODEL"
}
}
</code>
<code>package com.envisions.people.viewmodels
import android.location.Location
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.envisions.people.api.responses.DataArea
import com.envisions.people.api.responses.DataAssetItem
import com.envisions.people.api.responses.DataLocationItem
import com.envisions.people.api.responses.DataSurvey
import com.envisions.people.data.models.ResultState
import com.envisions.people.data.repository.AreaRepository
import com.envisions.people.data.repository.AssetRepository
import com.envisions.people.data.repository.InspectionRepository
import com.envisions.people.data.repository.LocationRepository
import kotlinx.coroutines.launch
import java.io.File
class CheckInViewModel(
private val locationRepository: LocationRepository?,
private val inspectionRepository: InspectionRepository?,
private val areaRepository: AreaRepository?,
private val assetRepository: AssetRepository?
) : ViewModel() {
var nearestLocation: DataLocationItem? = null
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
private var _error = MutableLiveData<String>()
var errorResponse: LiveData<String> = _error
val surveyItem = MutableLiveData<ArrayList<DataSurvey>>()
private val _areaList = MutableLiveData<ArrayList<DataArea?>?>()
val areaList: LiveData<ArrayList<DataArea?>?> = _areaList
private val _assetList = MutableLiveData<ArrayList<DataAssetItem>>()
val assetList: LiveData<ArrayList<DataAssetItem>> = _assetList
val allAssetsLoaded = MutableLiveData<Boolean>()
// LiveData for etCheckInNotes
val etCheckInNotesLiveData: MutableLiveData<String> = MutableLiveData()
// Combined LiveData for etCheckInNotes and surveyItem
val combinedLiveData: MediatorLiveData<CheckInData> = MediatorLiveData()
init {
combinedLiveData.addSource(surveyItem) { surveyItem ->
val checkInData = CheckInData(etCheckInNotesLiveData.value, surveyItem)
combinedLiveData.value = checkInData
}
combinedLiveData.addSource(etCheckInNotesLiveData) { notes ->
val checkInData = CheckInData(notes, surveyItem.value ?: arrayListOf())
combinedLiveData.value = checkInData
}
}
data class CheckInData(val notes: String?, val surveyItems: ArrayList<DataSurvey>)
fun setLocationViewModel(token: String, currentLat: Double, currentLon: Double) {
allAssetsLoaded.value = false
Log.e("CheckInViewModel", "latitude : $currentLat")
Log.e("CheckInViewModel", "latitude : $currentLon")
viewModelScope.launch {
locationRepository?.setLocation(token)
?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val locationDataList = result.data.data.toList()
// Access specific location data from locationResponse object
Log.e("CheckInViewModel", locationDataList.toString())
val nearestLocationCheck =
calculateNearestDistance(locationDataList, currentLat, currentLon)
Log.e(
"CheckInViewModel",
"Nearest Location : ${nearestLocationCheck.toString()}"
)
nearestLocation = nearestLocationCheck
getArea(token, nearestLocation?.id.orEmpty())
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_isLoading.value = false
}
}
}
}
}
fun getArea(token: String, locationId: String) {
var completedAssetCalls = 0
viewModelScope.launch {
areaRepository?.getArea(token, locationId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAreaList = _areaList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAreaList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_areaList.value =
currentAreaList // Update the MutableLiveData with the new list
// for (item in result.data.data ?: arrayListOf()) {
// Log.e(TAG, "result.data.data ${result.data.data}")
// _areaList.value?.add(item)
// }
for (area in _areaList.value ?: arrayListOf()) {
getAsset(token, area?.id.orEmpty(), object : FetchCallback {
override fun onDataLoaded() {
completedAssetCalls++
if (completedAssetCalls == _areaList.value?.size) {
allAssetsLoaded.value = true
_isLoading.postValue(false)
}
}
})
}
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
fun getAsset(token: String, areaId: String, fetchCallback: FetchCallback) {
viewModelScope.launch {
assetRepository?.getAsset(token, areaId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAssetList = _assetList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAssetList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_assetList.value =
currentAssetList // Update the MutableLiveData with the new list
//
// for (item in result.data.data?: arrayListOf()) {
// _assetList.value?.add(item)
// }
fetchCallback.onDataLoaded()
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
private fun calculateNearestDistance(
listLocation: List<DataLocationItem>?,
currentLat: Double,
currentLon: Double
): DataLocationItem? {
var nearestLocationItem: DataLocationItem? = null
var nearestDistance = Float.MAX_VALUE
for (itemLocation in listLocation ?: arrayListOf()) {
val result = FloatArray(1)
val (latitudeStr, longitudeStr) = itemLocation.coordinate.split(", ")
Location.distanceBetween(
currentLat,
currentLon,
latitudeStr.toDouble(),
longitudeStr.toDouble(),
result
)
val distance = result[0]
Log.e("CheckInViewModel", "Distance : ${distance.toInt()}, Item : $itemLocation")
if (distance < nearestDistance) {
nearestDistance = distance
nearestLocationItem = itemLocation
}
}
Log.e(
"CheckInViewModel",
"Nearest Distance : ${nearestDistance.toInt()}, Nearest Item : $nearestLocationItem"
)
if (nearestDistance.toInt() > (nearestLocationItem?.radius?.toInt()
?: 500)
) nearestLocationItem = null
return nearestLocationItem
}
fun postCheckIn(
token: String,
notes: String,
locationId: String,
assetId: ArrayList<DataAssetItem>,
fileList: ArrayList<File>,
surveyList: ArrayList<DataSurvey>
) =
inspectionRepository?.postInspection(
token,
notes,
locationId,
assetId,
fileList,
surveyList
)
fun getSurveyGeneral(token: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, null)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
}
surveyItem.postValue(listSurvey as ArrayList<DataSurvey>?)
val arrayTest = ArrayList<Any?>()
surveyItem.value?.forEach { data ->
data.items.forEach { item ->
Log.e(TAG, "item: $item")
arrayTest.add(item.valueItem)
Log.e(TAG, "arraytest : $arrayTest")
}
}
}
}
}
}
}
fun getSurveyAsset(token: String, assetId: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, assetId)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
} as ArrayList<DataSurvey>
val updatedList = ArrayList<DataSurvey>()
surveyItem.value?.forEach { dataSurvey ->
updatedList.add(dataSurvey)
}
// Now, iterate through listSurvey and add elements with unique names
listSurvey.forEach { newSurveyGet ->
val isNew =
updatedList.none { existingSurvey -> existingSurvey.name == newSurveyGet.name }
if (isNew) {
updatedList.add(newSurveyGet)
}
}
surveyItem.postValue(updatedList)
Log.e(TAG, "surveyItem = ${surveyItem.value}")
}
}
}
}
}
fun updateSurveyItemValueItem(surveyId: String, itemId: String, newValue: Any?) {
val updatedList = surveyItem.value?.map { survey ->
if (survey.id == surveyId) {
survey.copy(
items = survey.items.map { item ->
if (item.id == itemId) {
item.copy(valueItem = newValue)
} else {
item
}
}
)
} else {
survey
}
}?.toMutableList()
updatedList?.let { surveyItem.value = it as ArrayList<DataSurvey> }
}
interface FetchCallback {
fun onDataLoaded()
}
companion object {
private const val TAG = "CHECKINVIEWMODEL"
}
}
</code>
package com.envisions.people.viewmodels
import android.location.Location
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.envisions.people.api.responses.DataArea
import com.envisions.people.api.responses.DataAssetItem
import com.envisions.people.api.responses.DataLocationItem
import com.envisions.people.api.responses.DataSurvey
import com.envisions.people.data.models.ResultState
import com.envisions.people.data.repository.AreaRepository
import com.envisions.people.data.repository.AssetRepository
import com.envisions.people.data.repository.InspectionRepository
import com.envisions.people.data.repository.LocationRepository
import kotlinx.coroutines.launch
import java.io.File
class CheckInViewModel(
private val locationRepository: LocationRepository?,
private val inspectionRepository: InspectionRepository?,
private val areaRepository: AreaRepository?,
private val assetRepository: AssetRepository?
) : ViewModel() {
var nearestLocation: DataLocationItem? = null
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
private var _error = MutableLiveData<String>()
var errorResponse: LiveData<String> = _error
val surveyItem = MutableLiveData<ArrayList<DataSurvey>>()
private val _areaList = MutableLiveData<ArrayList<DataArea?>?>()
val areaList: LiveData<ArrayList<DataArea?>?> = _areaList
private val _assetList = MutableLiveData<ArrayList<DataAssetItem>>()
val assetList: LiveData<ArrayList<DataAssetItem>> = _assetList
val allAssetsLoaded = MutableLiveData<Boolean>()
// LiveData for etCheckInNotes
val etCheckInNotesLiveData: MutableLiveData<String> = MutableLiveData()
// Combined LiveData for etCheckInNotes and surveyItem
val combinedLiveData: MediatorLiveData<CheckInData> = MediatorLiveData()
init {
combinedLiveData.addSource(surveyItem) { surveyItem ->
val checkInData = CheckInData(etCheckInNotesLiveData.value, surveyItem)
combinedLiveData.value = checkInData
}
combinedLiveData.addSource(etCheckInNotesLiveData) { notes ->
val checkInData = CheckInData(notes, surveyItem.value ?: arrayListOf())
combinedLiveData.value = checkInData
}
}
data class CheckInData(val notes: String?, val surveyItems: ArrayList<DataSurvey>)
fun setLocationViewModel(token: String, currentLat: Double, currentLon: Double) {
allAssetsLoaded.value = false
Log.e("CheckInViewModel", "latitude : $currentLat")
Log.e("CheckInViewModel", "latitude : $currentLon")
viewModelScope.launch {
locationRepository?.setLocation(token)
?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val locationDataList = result.data.data.toList()
// Access specific location data from locationResponse object
Log.e("CheckInViewModel", locationDataList.toString())
val nearestLocationCheck =
calculateNearestDistance(locationDataList, currentLat, currentLon)
Log.e(
"CheckInViewModel",
"Nearest Location : ${nearestLocationCheck.toString()}"
)
nearestLocation = nearestLocationCheck
getArea(token, nearestLocation?.id.orEmpty())
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_isLoading.value = false
}
}
}
}
}
fun getArea(token: String, locationId: String) {
var completedAssetCalls = 0
viewModelScope.launch {
areaRepository?.getArea(token, locationId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAreaList = _areaList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAreaList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_areaList.value =
currentAreaList // Update the MutableLiveData with the new list
// for (item in result.data.data ?: arrayListOf()) {
// Log.e(TAG, "result.data.data ${result.data.data}")
// _areaList.value?.add(item)
// }
for (area in _areaList.value ?: arrayListOf()) {
getAsset(token, area?.id.orEmpty(), object : FetchCallback {
override fun onDataLoaded() {
completedAssetCalls++
if (completedAssetCalls == _areaList.value?.size) {
allAssetsLoaded.value = true
_isLoading.postValue(false)
}
}
})
}
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
fun getAsset(token: String, areaId: String, fetchCallback: FetchCallback) {
viewModelScope.launch {
assetRepository?.getAsset(token, areaId)?.collect { result ->
when (result) {
is ResultState.Loading -> {
// Handle loading state, e.g., show a progress indicator
_isLoading.value = true
}
is ResultState.Success -> {
val currentAssetList = _assetList.value
?: arrayListOf() // Get the current value or create an empty list if null
currentAssetList.addAll(
result.data.data ?: emptyList()
) // Add the new elements
_assetList.value =
currentAssetList // Update the MutableLiveData with the new list
//
// for (item in result.data.data?: arrayListOf()) {
// _assetList.value?.add(item)
// }
fetchCallback.onDataLoaded()
}
is ResultState.Error -> {
// Handle error, e.g., show Toast or navigate to error screen
// makeToast(context, result.error)
_error.postValue(result.error)
_isLoading.value = false
}
}
}
}
}
private fun calculateNearestDistance(
listLocation: List<DataLocationItem>?,
currentLat: Double,
currentLon: Double
): DataLocationItem? {
var nearestLocationItem: DataLocationItem? = null
var nearestDistance = Float.MAX_VALUE
for (itemLocation in listLocation ?: arrayListOf()) {
val result = FloatArray(1)
val (latitudeStr, longitudeStr) = itemLocation.coordinate.split(", ")
Location.distanceBetween(
currentLat,
currentLon,
latitudeStr.toDouble(),
longitudeStr.toDouble(),
result
)
val distance = result[0]
Log.e("CheckInViewModel", "Distance : ${distance.toInt()}, Item : $itemLocation")
if (distance < nearestDistance) {
nearestDistance = distance
nearestLocationItem = itemLocation
}
}
Log.e(
"CheckInViewModel",
"Nearest Distance : ${nearestDistance.toInt()}, Nearest Item : $nearestLocationItem"
)
if (nearestDistance.toInt() > (nearestLocationItem?.radius?.toInt()
?: 500)
) nearestLocationItem = null
return nearestLocationItem
}
fun postCheckIn(
token: String,
notes: String,
locationId: String,
assetId: ArrayList<DataAssetItem>,
fileList: ArrayList<File>,
surveyList: ArrayList<DataSurvey>
) =
inspectionRepository?.postInspection(
token,
notes,
locationId,
assetId,
fileList,
surveyList
)
fun getSurveyGeneral(token: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, null)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
}
surveyItem.postValue(listSurvey as ArrayList<DataSurvey>?)
val arrayTest = ArrayList<Any?>()
surveyItem.value?.forEach { data ->
data.items.forEach { item ->
Log.e(TAG, "item: $item")
arrayTest.add(item.valueItem)
Log.e(TAG, "arraytest : $arrayTest")
}
}
}
}
}
}
}
fun getSurveyAsset(token: String, assetId: String) {
_isLoading.postValue(true)
viewModelScope.launch {
inspectionRepository?.getSurvey(token, assetId)?.collect { result ->
when (result) {
is ResultState.Error ->
_error.postValue(result.error)
ResultState.Loading -> _isLoading.postValue(true)
is ResultState.Success -> {
_isLoading.postValue(false)
// _surveyItem.postValue(result.data)
val listSurvey = result.data.data.filter { dataSurvey ->
dataSurvey.items.any { surveyItem -> surveyItem.type.name == "checklist" }
} as ArrayList<DataSurvey>
val updatedList = ArrayList<DataSurvey>()
surveyItem.value?.forEach { dataSurvey ->
updatedList.add(dataSurvey)
}
// Now, iterate through listSurvey and add elements with unique names
listSurvey.forEach { newSurveyGet ->
val isNew =
updatedList.none { existingSurvey -> existingSurvey.name == newSurveyGet.name }
if (isNew) {
updatedList.add(newSurveyGet)
}
}
surveyItem.postValue(updatedList)
Log.e(TAG, "surveyItem = ${surveyItem.value}")
}
}
}
}
}
fun updateSurveyItemValueItem(surveyId: String, itemId: String, newValue: Any?) {
val updatedList = surveyItem.value?.map { survey ->
if (survey.id == surveyId) {
survey.copy(
items = survey.items.map { item ->
if (item.id == itemId) {
item.copy(valueItem = newValue)
} else {
item
}
}
)
} else {
survey
}
}?.toMutableList()
updatedList?.let { surveyItem.value = it as ArrayList<DataSurvey> }
}
interface FetchCallback {
fun onDataLoaded()
}
companion object {
private const val TAG = "CHECKINVIEWMODEL"
}
}
And finally this is my implementation in the activity class.
<code>checkInViewModel.surveyItem.observe(this) { surveyData ->
if (surveyData.isNotEmpty()) {
surveyAdapter = SurveyContainerAdapter(checkInViewModel.surveyItem.value ?: arrayListOf(), this)
binding.rvSurveyInspection.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rvSurveyInspection.adapter = surveyAdapter
surveyAdapter.setOnItemClickCallback(object :
SurveyContainerAdapter.OnItemClickCallback {
override fun onItemClicked(data: DataSurvey, position: Int) {
if (position != -1) {
updateSurvey(position)
}
val foundAsset : ArrayList<DataAssetItem> = arrayListOf()
assetList.forEachIndexed { _, dataAssetItem ->
data.assets.forEach { assetsItem ->
if(assetsItem.assetId == dataAssetItem.id){
foundAsset.add(dataAssetItem)
return@forEachIndexed
}
}
}
if(foundAsset.isNotEmpty()){
foundAsset.forEach { assetItem ->
val foundAssetIndex = assetList.indexOf(assetItem)
assetList.removeAt(foundAssetIndex)
assetAdapter.notifyItemRemoved(foundAssetIndex)
assetAdapter.notifyItemRangeChanged(
foundAssetIndex,
assetList.size.minus(foundAssetIndex)
)
}
}
}
override fun onValueClicked(surveyId: String, itemId: String, newValue: Any?) {
checkInViewModel.updateSurveyItemValueItem(surveyId, itemId, newValue)
}
})
}
surveyData.forEach { dataSurvey ->
Log.e(TAG, "test $dataSurvey")
}
}
</code>
<code>checkInViewModel.surveyItem.observe(this) { surveyData ->
if (surveyData.isNotEmpty()) {
surveyAdapter = SurveyContainerAdapter(checkInViewModel.surveyItem.value ?: arrayListOf(), this)
binding.rvSurveyInspection.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rvSurveyInspection.adapter = surveyAdapter
surveyAdapter.setOnItemClickCallback(object :
SurveyContainerAdapter.OnItemClickCallback {
override fun onItemClicked(data: DataSurvey, position: Int) {
if (position != -1) {
updateSurvey(position)
}
val foundAsset : ArrayList<DataAssetItem> = arrayListOf()
assetList.forEachIndexed { _, dataAssetItem ->
data.assets.forEach { assetsItem ->
if(assetsItem.assetId == dataAssetItem.id){
foundAsset.add(dataAssetItem)
return@forEachIndexed
}
}
}
if(foundAsset.isNotEmpty()){
foundAsset.forEach { assetItem ->
val foundAssetIndex = assetList.indexOf(assetItem)
assetList.removeAt(foundAssetIndex)
assetAdapter.notifyItemRemoved(foundAssetIndex)
assetAdapter.notifyItemRangeChanged(
foundAssetIndex,
assetList.size.minus(foundAssetIndex)
)
}
}
}
override fun onValueClicked(surveyId: String, itemId: String, newValue: Any?) {
checkInViewModel.updateSurveyItemValueItem(surveyId, itemId, newValue)
}
})
}
surveyData.forEach { dataSurvey ->
Log.e(TAG, "test $dataSurvey")
}
}
</code>
checkInViewModel.surveyItem.observe(this) { surveyData ->
if (surveyData.isNotEmpty()) {
surveyAdapter = SurveyContainerAdapter(checkInViewModel.surveyItem.value ?: arrayListOf(), this)
binding.rvSurveyInspection.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rvSurveyInspection.adapter = surveyAdapter
surveyAdapter.setOnItemClickCallback(object :
SurveyContainerAdapter.OnItemClickCallback {
override fun onItemClicked(data: DataSurvey, position: Int) {
if (position != -1) {
updateSurvey(position)
}
val foundAsset : ArrayList<DataAssetItem> = arrayListOf()
assetList.forEachIndexed { _, dataAssetItem ->
data.assets.forEach { assetsItem ->
if(assetsItem.assetId == dataAssetItem.id){
foundAsset.add(dataAssetItem)
return@forEachIndexed
}
}
}
if(foundAsset.isNotEmpty()){
foundAsset.forEach { assetItem ->
val foundAssetIndex = assetList.indexOf(assetItem)
assetList.removeAt(foundAssetIndex)
assetAdapter.notifyItemRemoved(foundAssetIndex)
assetAdapter.notifyItemRangeChanged(
foundAssetIndex,
assetList.size.minus(foundAssetIndex)
)
}
}
}
override fun onValueClicked(surveyId: String, itemId: String, newValue: Any?) {
checkInViewModel.updateSurveyItemValueItem(surveyId, itemId, newValue)
}
})
}
surveyData.forEach { dataSurvey ->
Log.e(TAG, "test $dataSurvey")
}
}