generateBlocTemplate method

String generateBlocTemplate(
  1. ApiGenerationConfig config
)

Generates BLoC template with state management logic.

Creates the main BLoC class with proper event handling for both future and stream-based API methods.

Parameters:

  • config: API generation configuration

Implementation

String generateBlocTemplate(ApiGenerationConfig config) {
  final entityClass = typeResolver.resolveEntityClass(config);

  return '''${typeResolver.whenMethod(
    config.method,
    onStream: () => "import 'dart:async';",
    onFuture: () => '',
  )}
${config.returnData == 'body_bytes' ? "import 'dart:typed_data';" : ''}

import 'package:core/core.dart';
import 'package:flutter/material.dart';

import '../../../data/models/body/${config.apiName}_body.dart';
${config.isReturnDataModel ? '''import '../../../domain/entities/${config.apiName}_entity.dart';''' : ''}
import '../../../domain/usecases/${config.apiName}_use_case.dart';

part '${config.apiName}_event.dart';
part '${config.apiName}_state.dart';

class ${config.apiClassName}Bloc extends MorphemeBloc<${config.apiClassName}Event, ${config.apiClassName}State> {
${config.apiClassName}Bloc({
  required this.useCase,
}) : super(${config.apiClassName}Initial()) {
  on<Fetch${config.apiClassName}>((event, emit) async {
    emit(${config.apiClassName}Loading(event.body, event.headers, event.extra,),);
    ${typeResolver.whenMethod(
    config.method,
    onStream: () {
      return '''final results = useCase(event.body, headers: event.headers,);
    final completer = Completer();
    final List<$entityClass> buffer = [];
    _streamSubscription = results.listen(
      (result) {
        emit(
          result.fold(
            (failure) => ${config.apiClassName}Failed(
              event.body,
              event.headers,
              failure,
              event.extra,
            ),
            (success) {
              buffer.add(success);
              return ${config.apiClassName}Stream(
                event.body,
                event.headers,
                success,
                event.extra,
              );
            },
          ),
        );
      },
      onError: (error) {
        emit(
          ${config.apiClassName}Failed(
            event.body,
            event.headers,
            InternalFailure('An unexpected error occurred: \$error'),
            event.extra,
          ),
        );
        completer.complete();
      },
      onDone: () {
        emit(
          ${config.apiClassName}Success(
            event.body,
            event.headers,
            buffer,
            event.extra,
          ),
        );
        completer.complete();
      },
    );
    await completer.future;
  });
  on<Cancel${config.apiClassName}>((event, emit) async {
    _streamSubscription?.cancel();
    _streamSubscription = null;
    emit(${config.apiClassName}Canceled(event.extra));
  });
  on<Pause${config.apiClassName}>((event, emit) async {
    _streamSubscription?.pause();
    emit(${config.apiClassName}Paused(event.extra));
  });
  on<Resume${config.apiClassName}>((event, emit) async {
    _streamSubscription?.resume();
    emit(${config.apiClassName}Resumed(event.extra));
  });''';
    },
    onFuture: () {
      return '''_cancelableOperation = CancelableOperation.fromFuture(
      useCase(
        event.body,
        headers: event.headers,
        ${typeResolver.isApplyCacheStrategy(config.method) ? 'cacheStrategy: event.cacheStrategy,' : ''}
      ),
    );
    final result = await _cancelableOperation?.valueOrCancellation();

    if (result == null) {
      emit(${config.apiClassName}Canceled(event.extra));
      return;
    }
    emit(
      result.fold(
        (failure) => ${config.apiClassName}Failed(event.body, event.headers, failure, event.extra,),
        (success) => ${config.apiClassName}Success(event.body, event.headers, success, event.extra,),
      ),
    );
  });
  on<Cancel${config.apiClassName}>((event, emit) async {
    _cancelableOperation?.cancel();
    _cancelableOperation = null;
    emit(${config.apiClassName}Canceled(event.extra));
  });''';
    },
  )}

}

final ${config.apiClassName}UseCase useCase;

${typeResolver.whenMethod(
    config.method,
    onStream: () {
      return '''StreamSubscription<Either<MorphemeFailure, $entityClass>>? _streamSubscription;

@override
Future<void> close() {
  _streamSubscription?.cancel();
  _streamSubscription = null;
  return super.close();
}''';
    },
    onFuture: () {
      return '''CancelableOperation<Either<MorphemeFailure, $entityClass>>? _cancelableOperation;

@override
Future<void> close() {
  _cancelableOperation?.cancel();
  _cancelableOperation = null;
  return super.close();
}''';
    },
  )}
}''';
}