Search code examples
flutterdartconstructortypeerror

The following _TypeError was thrown building Builder: type 'int' is not a subtype of type 'List<int>' in type cast


I upgraded a codebase to null safety and ever since, it's been throwing this error

attempted some StackOverflow fixes but none worked[Error Image](https://i.sstatic.net/ogEfH.jpg)

I also change everything that needed a null check to nullsafety

class QuestionnaireScreen extends StatefulWidget {
  final Questionnaire questionnaire;

  QuestionnaireScreen({required this.questionnaire});

  @override
  _QuestionnaireScreenState createState() => _QuestionnaireScreenState();
}

class _QuestionnaireScreenState extends State<QuestionnaireScreen> {
  List<Question> get questions => widget.questionnaire.questions;
  late int questionIndex;
  Question get currentQuestion => questions[questionIndex];
  int get numberOfQuestions => questions.length;
  late List<int> chosenAnswers;
  bool get userHasAnsweredCurrentQuestion =>
      chosenAnswers[questionIndex] != null;
  String get instructions => widget.questionnaire.instructions;

  String getResultInterpretation() {
    // calculate user's total score
    int result = 0;
    for (int index = 0; index < numberOfQuestions; index++) {
      Question question = questions[index];
      int answerIndex = chosenAnswers[index];
      Answer answer = question.answers[answerIndex];
      int score = answer.score;

      result += score;
    }

    // determine interpretation for result
    List<Interpretation> interpretations = widget.questionnaire.interpretations;
    for (Interpretation interpretation in interpretations) {
      if (result >= interpretation.score) {
        return interpretation.text;
      }
    }

    // if something went wrong, return the worst interpretation
    return interpretations.last.text;
  }

  @override
  void initState() {
    super.initState();

    questionIndex = 0;

    //THIS IS TH ELING CAUSING ISSUES
    // STARTS HERE
    chosenAnswers = List<int>(numberOfQuestions);
    // ENDS HERE
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.questionnaire.name),
      ),
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              Padding(
                padding:
                    const EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0),
                child: Text(
                  instructions,
                  textAlign: TextAlign.justify,
                  style: TextStyle(
                    fontSize: 15,
                    fontWeight: FontWeight.w500,
                    color: Theme.of(context).colorScheme.secondary,
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(15.0),
                child: Card(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(
                        height: 16,
                      ),
                      Center(
                        child: DotsIndicator(
                          dotsCount: numberOfQuestions,
                          position: int.parse(questionIndex.toString()),
                          decorator: DotsDecorator(
                            size: Size.square(15),
                            activeSize: Size(18, 18),
                            activeColor: Theme.of(context).primaryColor,
                            color: Theme.of(context).disabledColor,
                          ),
                        ),
                      ),
                      SizedBox(
                        height: 24,
                      ),
                      Padding(
                        padding: const EdgeInsets.only(left: 30.0, right: 8.0),
                        child: Text(
                          currentQuestion.text,
                          style: TextStyle(
                              fontSize: 20, fontWeight: FontWeight.w700),
                          textAlign: TextAlign.left,
                        ),
                      ),
                      SizedBox(
                        height: 24,
                      ),
                      RadioButtonGroup(
                        activeColor: Theme.of(context).primaryColor,
                        labels: currentQuestion.answers
                            .map((answer) => answer.text)
                            .toList(),
                        onChange: (_, answerIndex) => setState(() {
                          chosenAnswers[questionIndex] = answerIndex;
                        }),
                        picked: !userHasAnsweredCurrentQuestion
                            ? ""
                            : currentQuestion
                                .answers[chosenAnswers[questionIndex]].text,
                      ),
                      SizedBox(
                        height: 20,
                      ),
                      Padding(
                        padding: const EdgeInsets.only(bottom: 20.0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: <Widget>[
                            Visibility(
                              visible: questionIndex != 0,
                              child: Button.accent(
                                buttonLabel: 'Back',
                                onPressed: () {
                                  onBackButtonPressed();
                                },
                              ),
                            ),
                            Button.primary(
                                buttonLabel: 'Next',
                                onPressed: () {
                                  userHasAnsweredCurrentQuestion
                                      ? onNextButtonPressed()
                                      : null;
                                })
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void onNextButtonPressed() {
    if (questionIndex < numberOfQuestions - 1) {
      setState(() {
        questionIndex++;
      });
    } else {
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(
          builder: (context) => ResultScreen(
            questionnaireName: widget.questionnaire.name,
            interpretation: getResultInterpretation(),
          ),
        ),
      );
    }
  }

  void onBackButtonPressed() {
    if (questionIndex > 0) {
      setState(() {
        questionIndex--;
      });
    }
  }
}

Line of code throwing error

chosenAnswers = List<int>(numberOfQuestions); 

Fixed Attempted

Tried changeing the error line to

chosenAnswers = numberOfQuestions as List<int>;

But didn't work either

Please who can this be fixed..?

I will appreciate help from everybody Output error


Solution

  • To initialize a list of length numberOfQuestions you can write

    chosenAnswers = List.generate(numberOfQuestions, (index) => 0);
    

    Which will initialize it with the value 0 on all indices. Although judging from

      bool get userHasAnsweredCurrentQuestion =>
          chosenAnswers[questionIndex] != null;
    

    you would want a list of nullable ints, so

    late List<int> chosenAnswers;
    

    needs to be

    late List<int?> chosenAnswers;
    

    and then you should initiate it as

    chosenAnswers = List.generate(numberOfQuestions, (index) => null);