reduce method

  1. @override
Future<CoreState?> reduce()

The reduce method is the action reducer. It may read the action state, the store state, and then return a new state (or null if no state change is necessary).

It may be synchronous (returning AppState or null) or async (returning Future<AppState> or Future<null>).

The StoreConnectors may rebuild only if the reduce method returns a state which is both not null and different from the previous one (comparing by identical, not equals).

Implementation

@override
Future<CoreState?> reduce() async {
  if (client == null) {
    throw const UserException('cannot start a visit');
  }

  final Map<String, dynamic> input = <String, dynamic>{
    'input': <String, dynamic>{
      'patientID': breakGlassEpisodeCreationInput?.patientID,
      'providerCode': breakGlassEpisodeCreationInput?.providerCode,
      'practitionerUID': breakGlassEpisodeCreationInput?.practitionerUID,
      'providerPhone': breakGlassEpisodeCreationInput?.providerPhone,
      'otp': breakGlassEpisodeCreationInput?.otp,
      'fullAccess': false,
      'patientPhone': breakGlassEpisodeCreationInput?.patientPhone,
    }
  };

  final http.Response result =
      await client!.query(startBreakGlassVisitMutation, input);

  if (result.statusCode != 200) {
    throw const UserException(
        'Failed to start a visit, check internet connection');
  }
  final Map<String, dynamic> data = client!.toMap(result);

  client!.close();

  final String? error = client!.parseError(data);

  if (error != null) {
    await captureException(
      errorStartingVisitEmergency,
      query: startBreakGlassVisitMutation,
      error: error,
      response: data,
      variables: input,
    );
    throw const UserException(
        'Failed to start a visit, unexpected error occurred'); // todo: create better messages
  }

  final EpisodeOfCarePayload episodeOfCarePayload =
      EpisodeOfCarePayload.fromJson(
          data['data']['startEpisodeByBreakGlass'] as Map<String, dynamic>);

  // save the open episode of care into the core state
  final ClinicalState? clinicalState = state.clinicalState?.copyWith
      .call(currentEpisodeOfCare: episodeOfCarePayload.episodeOfCare);
  final CoreState newState =
      state.copyWith.call(clinicalState: clinicalState);

  // for backward compatibility only
  // TODO: REMOVE AFTER REFACTORING PATIENT PROFILE
  final CurrentPatientInEpisode currentPatientInEpisode =
      CurrentPatientInEpisode();
  currentPatientInEpisode.fullAccess.add(false);
  currentPatientInEpisode.episodeOfCarePayload.add(episodeOfCarePayload);

  final PatientEdge patientEdge =
      PatientEdge(node: state.clinicalState?.patientPayload?.patientRecord);

  final List<PatientEdge?> list = List<PatientEdge?>.empty(growable: true);
  list.add(patientEdge);
  final PatientConnection patientConnection = PatientConnection(edges: list);
  currentPatientInEpisode.patientConnection.add(patientConnection);

  dispatch(
      NavigateAction<CoreState>.popAndPushNamed(patientProfilePageRoute));

  return newState;
}