getStepAfterStep method

  1. @override
RPStep? getStepAfterStep(
  1. RPStep? step,
  2. RPTaskResult? result
)
override

Returns the step after a specified step if there's any, taking the RPStepNavigationRules into consideration.

If the specified step is null then it returns the first step. Returns null if step was the last one in the sequence.

Implementation

@override
RPStep? getStepAfterStep(RPStep? step, RPTaskResult? result) {
  step?.timer?.cancel();
  RPStep? stepToReturn;

  void returnNextQuestion() {
    int nextIndex = (step != null) ? steps.indexOf(step) + 1 : 0;

    if (nextIndex < steps.length) {
      stepToReturn = steps[nextIndex];
    } else {
      stepToReturn = null;
    }
  }

  if (step == null) {
    stepToReturn = steps.first;
    return stepToReturn;
  }

  if (stepNavigationRules.containsKey(step.identifier)) {
    RPStepNavigationRule rule = stepNavigationRules[step.identifier]!;

    switch (rule.runtimeType) {
      case const (RPStepReorganizerRule):
        RPStepReorganizerRule reorganizerRule = rule as RPStepReorganizerRule;
        RPStepResult? stepResult;
        if (step.runtimeType == RPFormStep) {
          RPTaskResult? recentTaskResult = blocTask.lastTaskResult;
          RPStepResult? foundStepResult;

          if (recentTaskResult != null) {
            recentTaskResult.results.forEach((key, stepResult) {
              if (stepResult is RPStepResult) {
                try {
                  // ensure that we are looking up only until the first match
                  foundStepResult ??=
                      stepResult.getResultForIdentifier(step.identifier)
                          as RPStepResult;
                } catch (e) {
                  print(
                      "No matching result found in this FormStep, proceeding to the next one (if any)");
                }
              }
            });
          } else {
            throw ("Error: No task result is available");
          }
          stepResult = foundStepResult;
        } else {
          RPTaskResult? recentTaskResult = blocTask.lastTaskResult;
          RPStepResult foundStepResult;

          if (recentTaskResult != null) {
            foundStepResult = recentTaskResult
                .getStepResultForIdentifier(step.identifier) as RPStepResult;
          } else {
            throw ("Error: No task result is available");
          }
          stepResult = foundStepResult;
        }

        List identifiersToKeep = [];
        for (var element
            in (stepResult!.results["answer"] as List<RPChoice>)) {
          String id = reorganizerRule.reorderingMap[element.value]!;
          identifiersToKeep.add(id);
        }

        steps.removeWhere(
            (step) => !identifiersToKeep.contains(step.identifier));

        if (steps.last.runtimeType == RPCompletionStep) {
          RPStep lastStep = steps.last;
          steps.add(lastStep);
        }

        returnNextQuestion();

        break;
      case const (RPStepJumpRule):
        RPStepJumpRule jumpRule = (rule as RPStepJumpRule);
        RPStepResult? stepResult;
        if (step.runtimeType == RPFormStep) {
          RPTaskResult? recentTaskResult = blocTask.lastTaskResult;
          RPStepResult? foundStepResult;

          if (recentTaskResult != null) {
            recentTaskResult.results.forEach((key, stepResult) {
              if (stepResult is RPStepResult) {
                try {
                  // ensure that we are looking up only until the first match
                  foundStepResult ??=
                      stepResult.getResultForIdentifier(step.identifier)
                          as RPStepResult;
                } catch (e) {
                  print(
                      "No matching result found in this FormStep, proceeding to the next one (if any)");
                }
              }
            });
          } else {
            throw ("Error: No task result is available");
          }
          stepResult = foundStepResult;
        } else {
          RPTaskResult? recentTaskResult = blocTask.lastTaskResult;
          RPStepResult foundStepResult;

          if (recentTaskResult != null) {
            foundStepResult = recentTaskResult
                .getStepResultForIdentifier(step.identifier) as RPStepResult;
          } else {
            throw ("Error: No task result is available");
          }
          stepResult = foundStepResult;
        }

        String? answer =
            jumpRule.answerMap[stepResult!.results["answer"].first.value];

        bool hadStepId = false;
        for (var step in steps) {
          if (step.identifier == answer) {
            stepToReturn = step;
            hadStepId = true;
          }
        }
        if (!hadStepId) {
          returnNextQuestion();
        }

        break;
      case const (RPDirectStepNavigationRule):
        String destinationStepIdentifier =
            (rule as RPDirectStepNavigationRule).destinationStepIdentifier;
        for (var step in steps) {
          if (step.identifier == destinationStepIdentifier) {
            stepToReturn = step;
          }
        }
        break;
      default:
        throw ("Navigation Rule's type ${stepNavigationRules[step.identifier].runtimeType} is not a navigation rule type");
    }
  } else {
    returnNextQuestion();
  }

  return stepToReturn;
}