so let's say we had the following object for our quiz app and the aim is to keep the score of the answers as the user answers each question.

 

This object is a list of Maps , each Map contains questionText and questionAnswer keys, questionText has the question as a text and questionAnswer has a list of Maps as it's value. in that map we have text and score for each answer.

   var _questions = [
      {
        'questionText': 'What\'s your favorite color?',
        'questionAnswer': [
          {'text': 'Black', 'score': 10},
          {'text': 'Red', 'score': 5},
          {'text': 'Green', 'score': 3},
          {'text': 'White', 'score': 1},
        ],
      },
      {
        'questionText': 'What\'s your favorite animal?',
        'questionAnswer': [
          {'text': 'Rabbit', 'score': 3},
          {'text': 'Snake', 'score': 11},
          {'text': 'Elephant', 'score': 5},
          {'text': 'Lion', 'score': 9},
        ],
      },
      {
        'questionText': 'Who\'s your favorite instructor?',
        'questionAnswer': [
          {'text': 'Me', 'score': 1},
          {'text': 'You', 'score': 10},
          {'text': 'Them', 'score': 8},
          {'text': 'Us', 'score': 6},
        ],
      },
    ];

 

a reminder of how we accessed each answer at a given index, 

...(questions.elementAt(questionIndex)['questionAnswer']
                as List<Map<String, Object>>)
            .map((answer) {
          return Answer(
            onPressed: () => answerQuestion(answer['score']),
            answerText: answer['text'],
          );
        }).toList(),

 

1. ... is the spreader operater 

2. elementAt takes the question at the given index (questionIndex)

3. we have to specify the type to let dart know how to use the map, in this case it's List<Map<String,Object>> which is something like below at the given index: 

[
          {'text': 'Black', 'score': 10},
          {'text': 'Red', 'score': 5},
          {'text': 'Green', 'score': 3},
          {'text': 'White', 'score': 1},
       ]

 

4. map(answer) gives us access to each individual answer which is a map now looking like:

{'text': 'Black', 'score': 10}

5. for each answer we want to render an Answer widget with the answer text

.map((answer) {
          return Answer(
            onPressed: () => answerQuestion(answer['score']),
            answerText: answer['text'],
          );

6. Answer takes in a function for onPressed which is responsible for any action once the user presses the button. Usually, if we had no argument we would just pass in the name of the function as a pointer to be executed once the user presses the button. 

But now that we have an argument we can use an anonymous function () => which is not called at the spot, as a gateway and put our function inside that function such as () => MyFunction(). this will make sure whenever the user presses the button MyFunction() is executed. 

and now that we know we can do that we can pass in arguments to the function too, as we did above to keep track of the score. 

 

here's is what answerQuestion does:

it increases the totalScore based on the given score as an argument and we pass this as we did above. 

  var _totalScore = 0;

  void _answerQuestion(int score) {
    setState(() {
      _totalScore += score;
      _questionIndex = _questionIndex + 1;
    });

 

 

finally we use the totalScore as a result: 

note the _ before the name indicates the variable or method or objects are private and are only accessible from the current file. 

_questionIndex < _questions.length
            ? Quiz(
                questions: _questions,
                answerQuestion: _answerQuestion,
                questionIndex: _questionIndex,
              )
            : Result(_totalScore), // this is where totalScore being used