#Transitioning using guard

1 messages · Page 1 of 1 (latest)

north cosmos
#

Given that simple state machine for quiz (simplified)



const practiceMachine = createMachine(
  {

    id: 'practice',
    tsTypes: {} as import('./practice.typegen').Typegen0,
    schema: {
      context: {} as ContextType,
      events: {} as EventsType,
    },
    context: {
      index: 0,
      correct: 0,
      incorrect: 0,
      total: 3,
    },
    initial: 'answering',
    states: {
      answering: {
        initial: 'idle',
        states: {
          correct: {type: 'final'},
          incorrect: {type: 'final'},
          idle: {
            on: {
              SUBMIT_ANSWER: [
                {
                  target: 'correct',
                  cond: 'isCorrect',
                  actions: ['assignCorrect'],
                },
                {
                  target: 'incorrect',
                  actions: ['assignIncorrect'],
                },
              ],
            },
          },
        },
        on: {
          NEXT_QUESTION: ...
        },
      },
      summary: {
        on: {
          RETRY: {
            target: 'answering.idle',
            actions: ['reset'],
          },
        },
      },
    },
  },
  {
    actions: {
      assignIndex: assign({
        index: context => context.index + 1,
      }),
      assignIncorrect: assign({
        incorrect: context => context.incorrect + 1,
      }),
      assignCorrect: assign({
        correct: context => context.correct + 1,
      }),

      reset: assign({
        index: 0,
        correct: 0,
        incorrect: 0,
        total: 3,
      }),
    },
    guards: {
      isCorrect: (_, event) => event.isCorrect,
    },
  }
);

What is the better approach for transition from answering.idle to answering.correct or answering.incorrect using guard isCorrect: (_, event) => event.isCorrect, or to use specific action - then I probably need to check it on the UI (component level)
?

desert summit
#

What logic determines if the answer is correct?

#

I would put the answers in the machine and put the answer checking logic in there

#

E.g.:

// pseudocode
guards: {
  isCorrect: (context, event) => {
    return context.answers[event.questionId] === event.answer
  }
}
north cosmos
#

yeah for now it will be in the context like in your example. So I will do like this. But for example if I need to chck it via backend then I can simply use Callback service and fire an specific action depends on question correctness i get from BE? @desert summit

desert summit
#

Yes, or transition to a checkingAnswer state

#
checkingAnswer: {
  invoke: {
    src: (context, event) => checkAnswerAsync(event),
    onDone: [
      { cond: 'answerCorrect', ... },
      // answer incorrect
    ]
  }
}