arch-atlas

Create fetch newest books

Presentation (Integration)

03:43

Summary

This lesson focuses on creating the NewestBooksCubit to manage the state for the newest books section of the home screen, mirroring the process previously used for featured books. The instructor demonstrates scaffolding the presentation states (Loading, Success, Failure) and copies over the core logic from the existing Cubit to accelerate development. The newly created Cubit relies on the injected FetchNewestBooksUseCase to retrieve data and uses the Either.fold method to emit the appropriate state based on the result. Finally, the instructor reviews the overall Clean Architecture flow diagram, noting that the presentation logic layer is now fully established and ready to be integrated with the UI widgets in upcoming lessons.

Key Ideas

  • Presentation layer structure directly mirrors UI components by dedicating separate Cubits to distinct screen sections.
  • NewestBooksState encapsulates three primary operational states: Initial/Loading, Success, and Failure.
  • NewestBooksSuccess state carries a List<BookEntity> payload required for the UI to render the list.
  • NewestBooksFailure state carries a String error message to display feedback to the user.
  • FetchNewestBooksUseCase is injected into the Cubit constructor to isolate data-fetching logic from state management.
  • Either.fold evaluates the dual outcomes (Failure or Data) returned by the UseCase, mapping them directly to UI states.
  • Code reuse via duplicating similar Cubits accelerates boilerplate setup within the presentation layer.

Code Snippets

newest_books_state.dartdart
part of 'newest_books_cubit.dart';

@immutable
abstract class NewestBooksState {}

class NewestBooksInitial extends NewestBooksState {}

class NewestBooksLoading extends NewestBooksState {}

class NewestBooksSuccess extends NewestBooksState {
  final List<BookEntity> books;

  NewestBooksSuccess(this.books);
}

class NewestBooksFailure extends NewestBooksState {
  final String errMessage;

  NewestBooksFailure(this.errMessage);
}
newest_books_cubit.dartdart
import 'package:bloc/bloc.dart';
import 'package:bookly/features/home/domain/entities/book_entity.dart';
import 'package:bookly/features/home/domain/use_cases/fetch_newest_books_use_case.dart';
import 'package:meta/meta.dart';

part 'newest_books_state.dart';

class NewestBooksCubit extends Cubit<NewestBooksState> {
  NewestBooksCubit(this.fetchNewestBooksUseCase) : super(NewestBooksInitial());

  final FetchNewestBooksUseCase fetchNewestBooksUseCase;

  Future<void> fetchNewestBooks() async {
    emit(NewestBooksLoading());
    var result = await fetchNewestBooksUseCase.call();
    result.fold((failure) {
      emit(NewestBooksFailure(failure.message));
    }, (books) {
      emit(NewestBooksSuccess(books));
    });
  }
}

My Notes

The instructor leans heavily into copy-pasting from FeaturedBooksCubit to scaffold NewestBooksCubit. While this is pragmatic for speed during initial setup, it requires high vigilance to ensure all references (class names, emitted states, and injected UseCases) are correctly renamed. The architecture diagram shown at the end effectively grounds the student's progress: the bridge between the UseCase and Presentation Logic Holders (Cubits) is complete. The exact next step mapped out is connecting these Logic Holders directly to the Widgets. [Editor's note] Early in the video, the instructor noticed a minor spelling mistake in the directory name (newest vs newst) but chose to ignore it. In a professional workflow, it is highly recommended to fix such typos immediately using IDE refactoring tools to prevent path resolution and importing headaches later.