Search code examples
androidandroid-sqliteandroid-roomandroid-livedata

How can i get a list from livedata?


I'm working on an app that has transactions stored in a local SQLite local database, I'm using Room. I have 2 activities consisting of MainActivity where I have a recycler view with all the transactions (add, remove transactions), and also a button that takes you to the other activity (Chart activity) which has a chart of the transactions.

Now, I don't want to allow the user to go to the Chart activity if there are no transactions in the database (because there would be nothing to see there).

This is the query in my Dao:

@Query("SELECT * FROM transaction_table WHERE amount < 0 AND strftime('%m', creationDate) = :month")
LiveData<List<Transaction>> getNegativeTransactionsByMonth(String month);

My repository:

public LiveData<List<Transaction>> getAllNegativeTransactionsByMonth(String month) {
    return transactionDao.getNegativeTransactionsByMonth(month);
}

My ViewModel

public LiveData<List<Transaction>> getAllNegativeTransactionsByMonth(String month) {
    return repository.getAllNegativeTransactionsByMonth(month);
}

MainActivity:

btnChart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final LiveData<List<Transaction>> viewModelData2 = transactionViewModel.getTransactionsByMonth(currentMonth);
            viewModelData2.observe(MainActivity.this, new Observer<List<Transaction>>() {
                @Override
                public void onChanged(List<Transaction> transactions) {
                    if(!transactions.isEmpty()) {
                        Intent intent = new Intent(getApplicationContext(), ChartActivity.class);
                        intent.putExtra("SELECTED_MONTH_NUMBER", SELECTED_MONTH_NUMBER);
                        startActivity(intent);
                    } else {
                        Toast.makeText(MainActivity.this, "Add a negative transaction to look at the chart", Toast.LENGTH_SHORT).show();
                    }
                }
            });

        }
    });

In the code above I have a listener for the button that takes you to the chart activity. I create an observer for the ViewModel data and place the logic inside the unchanged method, if the transactions are not empty then start the chart activity, if not show a toast.

The problem is that the if clause is run every time that a new transaction is created (which runs the unchanged method). I don't want this, I want the if clause to run only when I press the chart button.

I know that probably what I want to achieve is not possible to do with LiveData. That's why I'm asking for a way to get a list of transactions from the database and just check if it is empty or not. Any help is welcome. Thank you.


Solution

  • I'll suggest you take out an observer from setOnClickListener and use a boolean flag to go to the next activity.

    For example: Take one boolean isTransactionsEmpty and make one method to observe changes, set boolean to true or false as per the list is empty or not.

    boolean isTransactionsEmpty = true;
    
    void onCLicks(){
        btnChart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!isTransactionsEmpty) {
                    Intent intent = new Intent(getApplicationContext(), ChartActivity.class);
                    intent.putExtra("SELECTED_MONTH_NUMBER", SELECTED_MONTH_NUMBER);
                    startActivity(intent);
                } else {
                    Toast.makeText(MainActivity.this, "Add a negative transaction to look at the chart", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    
    void observeTransactionList(){
        transactionViewModel.getTransactionsByMonth(currentMonth).observe(MainActivity.this, new Observer<List<Transaction>>() {
            @Override
            public void onChanged(List<Transaction> transactions) {
                isTransactionsEmpty = transactions.isEmpty();
            }
        });
    }