0

Until now it's almost 10 days that I'm searching and watching YouTube videos for my answer, but I can't find it. please help me if you can.

Here Starts my MainActivity code:

    class MainActivity : ComponentActivity() {

lateinit var appDB: AppDatabase

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        MyVolleyTheme {

            appDB = AppDatabase.getDatabase(this)

                Surface(
                    modifier = Modifier
                        .fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {

                    Column(
                        horizontalAlignment = Alignment.CenterHorizontally,
                        modifier = Modifier
                    ) {

                        Spacer(modifier = Modifier.height(30.dp))

                        val text1 = remember { mutableStateOf("") }
                        TextField(
                            modifier = Modifier
                                .height(60.dp)
                                .fillMaxWidth()
                                .padding(0.dp),
                            value = text1.value,
                            onValueChange = { nextText ->
                                text1.value = nextText
                            },
                            label = {
                                Text(
                                    modifier = Modifier.padding(0.dp),
                                    text = "LastName",
                                    textAlign = TextAlign.Center,
                                    fontSize = 13.sp
                                )
                            },
                            singleLine = true,
                            trailingIcon = {
                                IconButton(onClick = {

                                }) {
                                    Icon(
                                        imageVector = Icons.Filled.Face,
                                        contentDescription = "lastName",
                                        modifier = Modifier.size(25.dp)
                                    )
                                }
                            },
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.Text,
                                imeAction = ImeAction.Next
                            ),
                        )

                        val text2 = remember { mutableStateOf("") }
                        TextField(
                            modifier = Modifier
                                .height(60.dp)
                                .fillMaxWidth()
                                .padding(0.dp),
                            value = text2.value,
                            onValueChange = { nextText ->
                                text2.value = nextText
                            },
                            label = {
                                Text(
                                    modifier = Modifier.padding(0.dp),
                                    text = "Age",
                                    textAlign = TextAlign.Center,
                                    fontSize = 13.sp
                                )
                            },
                            singleLine = true,
                            trailingIcon = {
                                IconButton(onClick = {

                                }) {
                                    Icon(
                                        imageVector = Icons.Filled.Person,
                                        contentDescription = "Age",
                                        modifier = Modifier.size(25.dp)
                                    )
                                }
                            },
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.Number,
                                imeAction = ImeAction.Done
                            ),
                        )

                        Button(onClick = {
                            if (text1.value.isNotEmpty() && text2.value.isNotEmpty()) {

                                val example = User(null, text1.value, text2.value.toInt())
                                lifecycleScope.launch(Dispatchers.IO) {
                                    appDB.userDao().insertAll(example)
                                }
                                Toast.makeText(
                                    this@MainActivity,
                                    "Data inserted successfully",
                                    Toast.LENGTH_LONG
                                ).show()
                                text1.value = ""
                                text2.value = ""

                            } else if (text1.value.isEmpty() || text2.value
                                    .isEmpty()
                            ) {
                                Toast.makeText(
                                    this@MainActivity,
                                    "Please fill the fields",
                                    Toast.LENGTH_LONG
                                ).show()
                            }
                        }) {
                            Text(text = "Save is database")
                        }

                        Spacer(modifier = Modifier.height(60.dp))


                        **// Showing a LazyColumn of our Database Content Here**


                    }
                }
            }
        }
    }
}
    

And my Room Entity code is:

    @Entity(tableName = "user_table")
data class User(
@PrimaryKey(autoGenerate = true) val uid: Int?,
@ColumnInfo(name = "last_name") val lastName: String?,
@ColumnInfo(name = "age") val age: Int?
 )

And my Room Dao:

@Dao
interface UserDao {
@Query("SELECT * FROM user_table")
fun getAll(): List<User>

@Query("SELECT * FROM user_table WHERE uid IN (:userIds)")
suspend fun loadAllByIds(userIds: IntArray): List<User>

@Query(
    "SELECT * FROM user_table WHERE last_name LIKE :last AND " + "age LIKE :age LIMIT 1"
)
suspend fun findByNameAge(last: String, age: Int): User

@Insert
suspend fun insertAll(vararg users: User)

@Delete
suspend fun delete(user: User)
}

And my Room Database:

 @Database(entities = [User::class], version = 1, exportSchema = false)
 abstract class AppDatabase : RoomDatabase() {
 abstract fun userDao(): UserDao

 companion object {
    @Volatile
    private var INSTANCE: AppDatabase? = null

    fun getDatabase(context: Context): AppDatabase {
        val tempInstance = INSTANCE
        if (tempInstance != null) {
            return tempInstance
        }
        synchronized(this) {
            val instance = Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                "user_database"
            ).build()
            INSTANCE = instance
            return instance
        }
    }
}
}

with these codes, I can successfully insert data into my Room database. but how can I show my database inside a lazycolumn?

Reza Zeraati
  • 303
  • 1
  • 8

2 Answers2

2

Here's the bare-bones code to display a Room database table in a LazyColumn:

// table:
@Entity(tableName = "word_table")
class Word(
    @PrimaryKey @ColumnInfo(name = "word") val text: String
)

// DAO:
@Query("SELECT * FROM word_table ORDER BY word COLLATE NOCASE ASC")
fun getAlphabetizedWords(): Flow<List<Word>>

@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(word: Word)

// repository:
val allWords: Flow<List<Word>> = wordDao.getAlphabetizedWords()

suspend fun insert(word: Word) {
    wordDao.insert(word)
}

// viewModel:
val allWords: LiveData<List<Word>> = repository.allWords.asLiveData()

fun insert(word: Word) = viewModelScope.launch {
    repository.insert(word)
}

// simplified composable:
@Composable
fun WordList() {
   val list by mWordViewModel.allWords.observeAsState(listOf())

   LazyColumn() {
      items(list) { word ->
         Row() {
            Text(word.text)
         }
      }
   }
}
dslamnig
  • 83
  • 1
  • 10
  • Jean-François Fabre and Ethan, before you delete this answer, too, please note that this is not a duplicate question. This code is not my answer to another question - this code is from my _question_. I advise you read the posts more carefully before taking (drastic) action. – dslamnig Oct 30 '22 at 17:34
1

To show all records from your DB to lazyColumn, call getAll() method from your DAO class to respository class. In my app, I have used a coroutineScope to call method from DAO to Repository class.

fun getAllEmployees() {
    coroutineScope.launch(Dispatchers.IO) {
        allEmployees.postValue(employeeDao.getAllEmployees())
    }
}

After adding getAllEmployees() function to Repository class, I have accessed it from viewmodel class like below:

@HiltViewModel
class HomeViewModel @Inject constructor(private val employeeRepository: 
EmployeeRepository) :
ViewModel() {

fun getAllEmployees(){
    employeeRepository.getAllEmployees()
}

Now, call getAllEmployees() from viewmodel class to mainActivity class as below:

homeViewModel.getAllEmployees()
val lazyListState = rememberLazyListState()
Scaffold(
    topBar = {
        CustomToolbar(title = stringResource(id = R.string.app_name), openDrawer)
    },
    content = {
        val employeeList: List<Employee> by homeViewModel.employeeList.observeAsState(initial = listOf())
        if (employeeList.isNotEmpty()) {
            Surface(color = Color.White, modifier = Modifier.fillMaxSize()) {
                LazyColumn(
                    modifier = Modifier.padding(vertical = 4.dp),
                    state = lazyListState
                ) {
                    items(items = employeeList) { emp ->
                        EmployeeCard(employee = emp, navController = navController)
                    }
                }
            }
        } else {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(20.dp),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Text(
                    "No employees onboarded yet.",
                    fontSize = 20.sp,
                    modifier = Modifier
                        .wrapContentWidth()
                        .wrapContentHeight(),
                    textAlign = TextAlign.Center
                )
            }
        }
    }

Check Github demo here: https://github.com/MansiKothari15/HRComposeApp. Check a Blog here: https://medium.com/jetpack-composers/jetpack-compose-room-db-b7b23bd6b189

Mansi Shah
  • 11
  • 1
  • 2
  • 6
  • thanks for answering. the last section when you say `homeViewModel.getAllEmployees()` I think something should be before it. it seems uncomplete. I saw the GitHub project, but I couldn't find it – Reza Zeraati Sep 29 '22 at 16:13
  • Sorry friend, but I saw The GitHub project and it is so hard to understand for we beginners. you have some libraries such as dagger-Hilt that is hard for us. and the project has so many files that I don't know what they are doing! isn't it possible to make such a project without Hilt and less code to be easier? – Reza Zeraati Sep 29 '22 at 16:24
  • Yes, it is possible without a hilt and all. You can directly create an object of the room database in your activity, access its DAO from there, query whatever you want, and show it in the UI. – Mansi Shah Sep 30 '22 at 04:49