Search code examples
javaandroidandroid-room

Is it necessary to always create a viewmodel to perform a simple query or can I access the database from my repository?


I am working with a student roll call application, I am using the Room database: Dao, Repository, ViewModel, I have the following tables: Group, Student, StudentGroup, AttendanceRecord, AttendanceStatus, etc.

Assuming I'm going to take attendance today in group A. So I have an activity to take attendance, in this case I need to work with several database tables: StudentGroup to see the students linked to this group, AttendanceRecord to create the attendance record for today's date, AttendanceStatus to save the status of attendance of each student on today's date (attended, absent, requested permission, etc.), Group to display the name of the group in which attendance is being taken.

From the group table the only data I need is the name to display it on the screen, (the group id comes from getIntent().getExtras()), in this case I need GroupViewModel to get the name String or can I just use my repository?

GroupRepo

public String getName(long idGroup){
    Callable<String> callable = () -> groupDao.getName(idGroup);
    String name = null;

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Future<String> future = executorService.submit(callable);
    try {
        name = future.get();
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return name;
}

Group ViewModel

private GrupoRepo groupRepo;
private LiveData<List<Group>> groupList;
private MutableLiveData<Integer> enableDisable = new MutableLiveData<Integer>();

public GrupoViewModel(@NonNull Application application) {
    super(application);
    groupRepo = new GroupRepo(application);
    enableDisable.setValue(MySettings.getMainView(application.getApplicationContext()));
    groupList = Transformations.switchMap(enableDisable,
            filter -> groupRepo.getFilteredGroups(filter));
}

public void setFilter(Integer enableDisable) {
    this.enableDisable.setValue(enableDisable);
}

public LiveData<List<Group>> getGroupList(){
    return groupList;
}

public String getName(long idGroup){
    return groupRepo.getName(idGroup);
}

If I only need the name of the group, I think it is much simpler and more useful to obtain it directly from the repository, if I create an instance of GroupViewModel, a list of groups that I do not need in this activity will be initialized. Is that correct or have I misunderstood?

Which tables do I need to instantiate your ViewModel in my list pass activity considering the uses I mentioned above?


Solution

  • One of the primary benefits of using a ViewModel is that it's designed to outlive the lifecycle of your UI components (Activity and Fragment), which means you don't have to worry about data surviving configuration changes.

    LiveData only receives updates when it's value changes. So an observer in your activity will only be triggered when you have new/different data.

    Your getName function is using an Executor to perform some database I/O, which you definitely don't want to call directly in your activity. I suggest creating another LiveData field to encompass it and observe it in your Activity. You can certainly bypass the ViewModel, but then you're missing out on the benefits explained above.

    In case you haven't read them yet, best places to start:

    Also, great time to learn Kotlin, because coroutines make this type of code so much easier to write and maintain.