问题
I have a Cloud Firebase database with a questions collection. Each question has a list of map options.
I'm using Flutter and have the following classes for question and option:
class Question {
final String text;
final List<Option> options; // I have tried changing this to List<dynamic> but it doesn't help
final String reference;
Question(this.text, this.options, this.reference);
Question.fromMap(Map<String, dynamic> map, {this.reference}) :
text = map['text'],
options = map['options']; // here the error happens
Question.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.documentID);
}
and option
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<String, dynamic> map) :
text = map['text'],
votes = map['votes'];
}
I really have no idea how I can fix this. This kind of error seems to be everywhere on the internet, though. Any help is appreciated.
Update
For your information: options is an array of map in Cloud Firestore.
I changed my code based on the two answers below to:
factory Question.fromMap(Map<String, dynamic> map) {
var options = map['options'];
var text = map['text'];
var reference = map['documentID'];
List<Option> optionsList = options.cast<Option>();
return new Question(
text = text,
options = optionsList,
reference = reference
);
}
factory Question.fromSnapshot(DocumentSnapshot snapshot) {
return Question.fromMap(snapshot.data);
}
Still, I get this error: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Option' in type cast
I have seen and tried so many answers and all seem to say the same. I just can't figure this out.
Screenshot of Cloud Firestore:
回答1:
I've met with this problem before, I solved with
this is my code you can convert it to yours:
UserModel.fromSnapshot(DocumentSnapshot snapshot)
: documentReference = snapshot.reference,
username = snapshot['username'],
firstName = snapshot['firstName'],
lastName = snapshot['lastName'],
picture = snapshot['picture'],
routes = Map.from(snapshot['routes']),
avgScore = snapshot['avgScore'];
}
what your field type on cloud_firestore ?
if its a Map try to use Map.from()
if it's a List try to use List.from()
and change your local field the same type.
回答2:
This code is more readable than your suggested solution. I used it in my project.
var optionsMap = map['options'] as List;
List<Option> optionsList = optionsMap.map((o) => Option.fromMap(o.cast<String, dynamic>())).toList();
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<dynamic, dynamic> map) : // notice Map<dynamic, dynamic> here
text = map['text'],
votes = map['votes'];
}
Source: How to fix this Error: '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'
回答3:
After encountering similar issues this worked perfectly for me:
class Question {
final String text;
final List<Option> options = [];
final String reference;
Question(this.text, this.options, this.reference);
Question.fromMap(Map<String, dynamic> map, {this.reference}){
text = map['text'];
if (map['options'] != null) {
map['options'].forEach((v) {
options.add(new Option.fromMap(v));
});
}
}
Question.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.documentID);
}
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<String, dynamic> map) :
text = map['text'],
votes = map['votes'];
}
回答4:
We are requesting a List but we are getting a List because our application cannot identify the type yet.
To remove this error, we have to explicitly cast the dynamic value. In place of
Question.fromMap(Map<String, dynamic> map, {this.reference}) :
text = map['text'],
options = map['options'];
use
factory Question.fromMap(Map<String, dynamic> map, {this.reference}) {
var optionsFromMap = map['options'];
//you can use both the steps to check which one will work perfectly for you
// List<Option> optionsList = new List<Option>.from(optionsFromMap)
List<Option> optionsList = optionsFromMap.cast<Option>();
return new Question(
text = map['text'],
options = map['options'];
);
}
the above code is working perfectly when I want List value
I hope this will help you.
回答5:
I ended up following @chipli onat advice and mix it with @harsh answer and finally got it to work. This is how my code looks like now:
class Question {
final String text;
final String reference;
final List<Map> options;
Question(this.text, this.options, this.reference);
factory Question.fromMap(Map<String, dynamic> map, String reference) {
var options = map['options'];
var text = map['text'];
List<Map> optionsList = options.cast<Map>();
return new Question(
text = text,
options = optionsList,
reference = reference
);
}
factory Question.fromSnapshot(DocumentSnapshot snapshot) {
return Question.fromMap(snapshot.data, snapshot.documentID);
}
}
and
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<dynamic, dynamic> map) : // notice Map<dynamic, dynamic> here
text = map['text'],
votes = map['votes'];
}
I'm sure this answer could be improved, but to be honest I don't understand entirely why it has to be so difficult. I hope this answer helps you.
来源:https://stackoverflow.com/questions/54851001/listdynamic-is-not-a-subtype-of-listoption