Reputation: 11
I have the following List of Maps:
var questions = [
{
'questionText': 'What is your favorite color?',
'answers': ['Black', 'Green', 'Red', 'White'],
},
{
'questionText': 'What is your favorite animal?',
'answers': ['Pig', 'Goat', 'Lion', 'Baboon'],
},
{
'questionText': 'What is your favorite number?',
'answers': ['1', '2', '3', '4'],
},
{
'questionText': 'What is your favorite game console?',
'answers': ['Xbox', 'Playstation', 'Nintendo', 'PC'],
},
{
'questionText': 'What is your favorite car model?',
'answers': ['Nissan', 'Toyota', 'Ford', 'Honda'],
},
];
I have an Example function that takes String type Arguments. If I wanted to use the keys one of the maps as that argument as such:
ExampleFunction(questions[1]['questionText']);
I get the following error:
The argument type 'Object?' can't be assigned to the parameter type 'String'.
I understand that using the map operator "[ ]" produces a nullable type according to documentation. It says to use an exclamation mark as follow to make it non-nullable:
ExampleFunction(questions[1]['questionText']!);
But this just produces the following error, this time without the explanation "?" mark:
The argument type 'Object' can't be assigned to the parameter type 'String'.
When I hover over the list it gives me:
List<Map<String, Object>>
Why are the keys appearing as an object when the only types I have in each map is String Keys, and List Answers?
Upvotes: 1
Views: 921
Reputation: 830
The problem is you don't have Map<String, String>.
{
'questionText': 'What is your favorite color?', -> <String, String>
'answers': ['Black', 'Green', 'Red', 'White'], -> <String, List>
}
Because the data inside the Map can be a String or a List the Object is assigned -> Map<String, Object>.
You can convert to String using toString()
questions[1]['questionText']!.toString();
Or you can create a class called question:
class Question{
String questionText;
List<String> answers;
Question(this.questionText, this.answers);
factory Question.fromMap(Map) {
return Question(map[questionText], map[answers]);
}
Map<String, dynamic> toMap() {
return {
"questionText": this.questionText,
"answers": this.answers,
}
}
}
With the Question class you can create a Question from a map Question.fromMap(questions[0]). And Convert to Map myQuestion.
Question question = Question("question", ["answer1", "answer2"]);
ExampleFunction(question.questionText);
or
Question question = Question.fromMap(myQuestionMap);
ExampleFunction(question.questionText);
and convert to map
Map mapQuestion = question.toMap();
Upvotes: 2
Reputation: 14435
The Map
has multiple value types: String
for the questionText
and List<String>
for the answers
. The closest matching type for those two is Object
.
You can either specify the type with the as
keyword:
questions[1]['questionText'] as String
or create a specific class
class Question {
final String questionText;
final List<String> answers;
Question({
required this.questionText,
required this.answers,
});
}
var questions = [
Question(
questionText: 'What is your favorite color?',
answers: ['Black', 'Green', 'Red', 'White'],
),
];
Upvotes: 2