I have a viewmodel and data classes that fetch the NASA api for photos of Mars. The user should be displayed images from a random date queried. I always need an image url (imgSrc in Photo class) returned. If no url (imgSrc) is found, refresh data until one is found and display it. This logic would need to return an imgSrc following launch of the application as well as after swiperefreshlayout if the user chooses to swipe to refresh. I have been stuck on this for a week with no resolve. What is the best way to handle this? Even if I have to refactor my code I would like to be pointed in the right direction.
Here is the actual project on github.
viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dev20.themarsroll.models.MarsPhotos
import com.dev20.themarsroll.models.Photo
import com.dev20.themarsroll.repository.MarsPhotoRepository
import com.dev20.themarsroll.util.Resource
import kotlinx.coroutines.launch
import retrofit2.Response
class MarsPhotoViewModel(
private val marsPhotoRepository: MarsPhotoRepository
): ViewModel() {
val marsPhotos: MutableLiveData<Resource<MarsPhotos>> = MutableLiveData()
init {
getRandomPhotos()
}
fun getCuriosityPhotos(solQuery: Int, roverQuery: Int, camera: String) = viewModelScope.launch {
marsPhotos.postValue(Resource.Loading())
val response = marsPhotoRepository.getCuriosityPhotos(solQuery, roverQuery, camera)
marsPhotos.postValue(handlePhotosResponse(response))
}
private fun handlePhotosResponse(response: Response<MarsPhotos> ) : Resource<MarsPhotos> {
if(response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
fun getRandomPhotos() {
getCuriosityPhotos((1..2878).random(), 5, "NAVCAM")
}
fun savePhoto(photo: Photo) = viewModelScope.launch {
marsPhotoRepository.upsert(photo)
}
fun getSavedPhotos() = marsPhotoRepository.getSavedPhotos()
fun deletePhoto(photo: Photo) = viewModelScope.launch {
marsPhotoRepository.deletePhoto(photo)
}
}
CuriosityFragment
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.View
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.dev20.themarsroll.R
import com.dev20.themarsroll.adapters.MarsPhotoAdapter
import com.dev20.themarsroll.util.Resource
import com.dev20.ui.MarsActivity
import com.dev20.ui.MarsPhotoViewModel
import kotlinx.android.synthetic.main.fragment_curiosity.*
class CuriosityFragment : Fragment(R.layout.fragment_curiosity) {
lateinit var viewModel: MarsPhotoViewModel
lateinit var marsPhotoAdapter: MarsPhotoAdapter
val TAG = "CuriosityFragment"
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as MarsActivity).viewModel
setupRecyclerView()
swipeLayout.setOnRefreshListener {
viewModel.getRandomPhotos()
swipeLayout.isRefreshing = false
}
marsPhotoAdapter.setOnItemClickListener {
val bundle = Bundle().apply {
putSerializable("photo", it)
}
findNavController().navigate(
R.id.action_curiosityFragment_to_cameraFragment,
bundle
)
}
viewModel.marsPhotos.observe(viewLifecycleOwner, { response ->
when(response) {
is Resource.Success -> {
hideProgressBar()
response.data?.let { curiosityResponse ->
marsPhotoAdapter.differ.submitList(curiosityResponse.photos)
}
}
is Resource.Error -> {
hideProgressBar()
response.message?.let { message ->
Log.e(TAG, "An Error occurred: $message")
}
}
is Resource.Loading -> {
showProgressBar()
}
}
})
}
private fun hideProgressBar() {
curiosityPaginationProgressBar.visibility = View.INVISIBLE
}
private fun showProgressBar() {
curiosityPaginationProgressBar.visibility = View.VISIBLE
}
private fun setupRecyclerView() {
marsPhotoAdapter = MarsPhotoAdapter()
rvCuriosityPhotos.apply {
adapter = marsPhotoAdapter
layoutManager = LinearLayoutManager(activity)
}
}
}
MarsPhoto data class
data class MarsPhotos(
val photos: MutableList<Photo>,
val camera: MutableList<Camera>
)
Photo data class
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.google.gson.annotations.SerializedName
import java.io.Serializable
@Entity(
tableName = "photos"
)
@TypeConverters
data class Photo(
@PrimaryKey(autoGenerate = true)
var id: Int? = null,
@SerializedName("earth_date")
val earthDate: String,
@SerializedName("img_src")
val imgSrc: String,
val sol: Int,
@SerializedName("rover_id")
val rover: Int,
) : Serializable
from How can I check to see if JSON data is null without an infinite loop?
No comments:
Post a Comment