skip to Main Content

What is best practice of bloc usage with nested data, when I have a list view, a detail view of the selected record and maybe a detail view of a subrecord?

Let’s say I have an app, showing some reports.

Option A)
One bloc for each view (e.g. AllReportsBloc, ReportsDetailBloc, ContactDetailBloc)

image of architecture option a

Option B)
One single bloc for all three views (e.g. ReportsBloc)

image of architecture option b

I’ve tried both of them but neither option a nor option b seems to be a solid solution

The problem with Option A)
With three different bloc’s I also have three different states of the same data source. If I change data of a single record for example, I’ll handle this over ReportsDetailBloc. So the state of ReportsDetailBloc will change. But the same record is also represented in the state of AllRecordsBloc, but here it’s still the old data. That’s needs me to think about bloc-to-bloc communication, but I don’t want to connect bloc through presentation as described in the official bloc docs. Connecting blocks via the presentation layer does not seem to be consistent with the idea of reactive programming, in my opinion. And it’s hard to maintain as I have to know where I placed this connections in the whole ui.

The problem with Option B)
One single bloc may become huge and complex. And it’s hard to trigger the ui on a granular level. So I end up in defining tons of status definitions (like allReportsLoading, singleReportLoading, singleContactLoading, allReportsLoadingError, singleReportLoadingError, …) to precisely target state changes in the ui.

Does anyone has an advice for me? Is there an Option C?

2

Answers


  1. I didn’t understand exactly what the problem is, now you have 3 blocs separated from the Zosh A that you used, when you change it, it doesn’t change in the others?
    What is the code you typed? Can you put it in Github or send a part of your code so that it can be helped better

    Login or Signup to reply.
  2. Option A is the ideal answer.

    Since all of the blocs depends on the same repository, you can create a stream or a variable that can hold the updated Reports inside the repository.

    Here’s an example from bloc‘s Todos app.

    Inside your `blocs, create an event that can automatically handle the updates coming from your Repository.
    In the Todos example, they named it as TodosOverviewSubscriptionRequested.

    Here’s the method for that event:

      Future<void> _onSubscriptionRequested(
        TodosOverviewSubscriptionRequested event,
        Emitter<TodosOverviewState> emit,
      ) async {
        emit(state.copyWith(status: () => TodosOverviewStatus.loading));
    
        await emit.forEach<List<Todo>>(
          _todosRepository.getTodos(),
          onData: (todos) => state.copyWith(
            status: () => TodosOverviewStatus.success,
            todos: () => todos,
          ),
          onError: (_, __) => state.copyWith(
            status: () => TodosOverviewStatus.failure,
          ),
        );
      }
    

    This will listen to the updates coming from the exposed stream of the repository. In this way, you avoided the bloc-to-bloc communications and handled the logic for single-source of data properly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search