Home > Software engineering >  In API get method, I am encountering the error 'List<dynamic>' is not a subtype of t
In API get method, I am encountering the error 'List<dynamic>' is not a subtype of t

Time:01-11

Here goes the Questions class which is used further in the list

class Questions {
  final String question;
  final String correctAnswer;
  final incorrectAnswers;

  Questions(
      {required this.question,
      required this.correctAnswer,
      required this.incorrectAnswers});
}

This is the API get block. The List with the type Questions is declared and then the items are appended

 List<Questions> questions = [];
  Future<List<Questions>> getRequest() async {
    final String url =
        'https://opentdb.com/api.php?amount=10&category=${widget.selectedItem[1]}&difficulty=${widget.selectedItem[0].toLowerCase()}&type=multiple';
    final response = await http.get(Uri.parse(url));
    var responseData = jsonDecode(response.body.toString());
    // var responseData = json.decode(response.body);

    //Creating a list to store input data;
    for (var eachquestion in responseData["results"]) {
      Questions fquestion = Questions(
          question: eachquestion["question"],
          correctAnswer: eachquestion["correct_answer"],
          incorrectAnswers: eachquestion["incorrect_answers"]);

      //Adding user to the list.
      questions.add(fquestion);
    }
    return questions;
  }

and this one is the implementation of the Future builder

Also, the FutureBuilder lines shows that "type 'List<dynamic>' is not a subtype of type 'List<String>'"

FutureBuilder(
            future: getRequest(),
            builder: ((context, snapshot) {
              if (!snapshot.hasData) {
                return const Text("Loading...");
              } else {
                String answer = questions[indexVal].correctAnswer;
                List<String> options = [questions[indexVal].correctAnswer]  
                    questions[indexVal].incorrectAnswers;
                options.shuffle;
                return Container(
                    padding: const EdgeInsets.fromLTRB(15, 150, 15, 0),
                    child: Column(
                        children: (num == 10)
                            ? [
                                ScorePage(
                                  score: score,
                                )
                              ]
                            : [
                                Container(
                                  margin: const EdgeInsets.only(bottom: 30),
                                  child: Center(
                                    child: Row(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.center,
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Expanded(
                                          child: Text(
                                              questions[indexVal].question,
                                              style: const TextStyle(
                                                  fontSize: 20,
                                                  fontWeight: FontWeight.bold)),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                                Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  children: [
                                    indOption(
                                        nextQues: nextQues,
                                        optionVal: options[0]),
                                    indOption(
                                        nextQues: nextQues,
                                        optionVal: options[1]),
                                    indOption(
                                        nextQues: nextQues,
                                        optionVal: options[2]),
                                    indOption(
                                        nextQues: nextQues,
                                        optionVal: options[3]),
                                  ],
                                ),
                              ]));
              }
            }),
          )

Also, let me know the reason and solution behind it!

CodePudding user response:

The problem is in your model's incorrectAnswers field. Its data type is dynamic so you have to type cast it as below.

List options = [questions[indexVal].correctAnswer] questions[indexVal].incorrectAnswers as string;

CodePudding user response:

As the other answer pointed out, the biggest problem is the type of your Questions class. This is what you should change it to (I also changed the name to Question since the object stores one question and not multiple):

class Question {
  final String question;
  final String correctAnswer;
  final List<String> incorrectAnswers;

  Questions(
      {required this.question,
      required this.correctAnswer,
      required this.incorrectAnswers});
}

Now, inside the FutureBuilder you need to combine the single correct answer with the x incorrect ones into one list of options, like this:

List<String> options = [
  questions[indexVal].correctAnswer,
  ...questions[indexVal].incorrectAnswers 
 // The three dots means since incorrectAnswers is a list and you don't want a list of lists,
 // it should take out the values and put them to the outer list one by one.
];

If you get the similar error again, keep in mind that you might need to typecast the values from the API in your constructor:

Question fquestion = Question(
    question: eachquestion["question"] as String,
    correctAnswer: eachquestion["correct_answer"] as String,
    incorrectAnswers: eachquestion["incorrect_answers"] as List<String>,
);

This should do the trick!

CodePudding user response:

The issue was that the list of incorrectAnswers was dynamic and I was adding that to the List of type string. So I added the individual element of the list. Since it is not a scalable method, I would like to hear more advices from the geeks.

  • Related