My app has a navigation bar and in one navBarItem I have two tabs, I want to read images and their caption I have stored in my firebase firestore collection into a LazyColumn in one of the tabs. Here is how my DataException and GalleryRepo class looks like
data class DataOrException<T, E : Exception> (
var data: T? = null,
var e: E? = null
)
@Singleton
class GalleryRepo @Inject constructor(
private val queryImageData: Query
) {
fun getImagesFromFirestore(): DataOrException<List<PQImageGallery>, Exception> {
val dataOrException = DataOrException<List<PQImageGallery>, Exception>()
try {
dataOrException.data = queryImageData.get()
.result.map { document -> document.toObject(PQImageGallery::class.java) }
} catch (e: FirebaseFirestoreException) {
dataOrException.e = e
}
return dataOrException
}
}
My data class
data class PQImageGallery (
var imageUrl: String? =null,
var caption: String? = null
)
ViewModels...
@HiltViewModel
class PQViewModel @Inject constructor(
private val repository: GalleryRepo
): ViewModel() {
var loading = mutableStateOf(false)
val data: MutableState<DataOrException<List<PQImageGallery>, Exception>> = mutableStateOf(
DataOrException(
listOf(),
Exception("")
)
)
init {
getGalleryCollection()
}
private fun getGalleryCollection() {
viewModelScope.launch {
loading.value = true
data.value = repository.getImagesFromFirestore()
loading.value = false
}
}
}
@Module
@InstallIn(SingletonComponent::class)
object RemoteImageModel {
@Provides
@Singleton
fun loadImagesInCollection() = FirebaseFirestore.getInstance()
.collection(IMAGE_COLLECTION)
}
My GalleryCollection composable file
@Composable
fun GalleryCollection(dataOrException: DataOrException<List<PQImageGallery>, Exception>) {
val images = dataOrException.data
images?.let {
LazyColumn {
items(items = images) { product ->
GalleryCard(pqImageGallery = product)
}
}
}
val e = dataOrException.e
e?.let {
Text(
text = e.message!!,
modifier = Modifier.padding(16.dp)
)
}
}
@Composable
fun GalleryCard(
pqImageGallery: PQImageGallery,
) {
Card(...) {
Box(modifier = Modifier
.fillMaxSize()
) {
pqImageGallery.imageUrl?.let { imageUrl ->
CoilImage(
data = imageUrl,
....
)
}
pqImageGallery.caption?.let { caption ->
Text(
text = caption,
...
)
}
}
}
}
My navBarItem that contains the two tabs called Home
class Home : ComponentActivity() {
private val viewModel: PQViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HomeScreen(viewModel)
}
}
}
@Composable
fun HomeScreen(
viewModel: PQViewModel
) {
val dataOrException = viewModel.data.value
val navController = rememberNavController()
val currentBackStack by navController.currentBackStackEntryAsState()
val currentDestination = currentBackStack?.destination
val currentScreen =
HomeTabRowScreens.find { it.route == currentDestination?.route } ?: GalleryView
Scaffold(
topBar = {
HomeScreenTabRow(
allScreens = HomeTabRowScreens,
onTabSelected = { newScreen ->
navController
.navigateSingleTopTo(newScreen.route)
},
currentScreen = currentScreen,
)
}
) { innerPadding ->
NavHost(
navController = navController,
startDestination = GalleryView.route,
modifier = Modifier.padding(innerPadding)
) {
composable(route = GalleryView.route) {
// GalleryTabScreen()
GalleryCollection(dataOrException = dataOrException)
}
composable(route = VirtualTourView.route) {
VirtualTourScreen()
}
}
}
}
fun NavHostController.navigateSingleTopTo(route: String) =
this.navigate(route) {
popUpTo(
this@navigateSingleTopTo.graph.findStartDestination().id
) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
Finally calling the Home class in my main screen(MainActivity)
NavHost(
..
) {
composable(NAV_HOME) {
Home()
}
composable(..) { ...}
}
The issue is when I run the app the tabs in the Home navBar doesn't show at all talk of loading the images from the firestore collection. Also, is there another way to instantiate a viewModel without having to create a class that extends ComponentActiviy?
If there's another way to achieve this kindly share.