Reputation: 192
I am storing user favorites to json file bu I am getting the following error:
Unhandled Exception: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' of 'other'
And I am adding the following data to the file:
{
3423: {
'ID': 3423,
'Title': 'Jupiter Ascending',
'Image': 'https://...'
}
}
The code is:
File jsonFile;
Directory dir;
String fileName = "Reading.json";
bool fileExists = false;
List<Map> fileContent;
@override
void initState() {
super.initState();
/*to store files temporary we use getTemporaryDirectory() but we need
permanent storage so we use getApplicationDocumentsDirectory() */
getApplicationDocumentsDirectory().then((Directory directory) {
dir = directory;
jsonFile = new File(dir.path + "/" + fileName);
fileExists = jsonFile.existsSync();
if (fileExists)
this.setState(
() => fileContent = json.decode(jsonFile.readAsStringSync()));
});
}
void createFile(Map content, Directory dir, String fileName) {
print("Creating file!");
File file = new File(dir.path + "/" + fileName);
file.createSync();
fileExists = true;
file.writeAsStringSync(json.encode(content));
}
void writeToFile(var key, var value) {
print("Writing to file!");
Map content = {key: value};
if (fileExists) {
print("File exists");
Map jsonFileContent = json.decode(jsonFile.readAsStringSync());
jsonFileContent.addAll(content);
jsonFile.writeAsStringSync(json.encode(jsonFileContent));
} else {
print("File does not exist!");
createFile(content, dir, fileName);
}
this.setState(() => fileContent = json.decode(jsonFile.readAsStringSync()));
print(fileContent);
}
I am confused and do not know how to solve the problem.
Upvotes: 0
Views: 773
Reputation: 31209
You have removed any traces of typing in your writeToFile
method which makes it so Dart cannot help you. The problem comes from:
void writeToFile(var key, var value) {
print("Writing to file!");
Map content = {key: value};
...
First, don't ever use var
as parameter type on a method. It is really bad because you allow all types which is properly not what you want.
In this case, the result of json.decode(jsonFile.readAsStringSync())
will be a Map<String, dynamic>
instance on runtime.
But the Map you are creating with Map content = {key: value};
is going to be of the type Map<dynamic, dynamic>
because it cannot predict the types for key and value when compiling the code.
Since you cannot put the content of a Map<dynamic, dynamic>
into Map<String, dynamic>
you get an error.
What you can do is to make the key
at least a String like:
void writeToFile(String key, var value) {
print("Writing to file!");
final content = {key: value};
...
I will also say you can help yourself if you are using var
and final
instead of trying typing the type manually. It is fine if you want the types but then you really need to explicit write the correct generic part of the type.
E.g. this is wrong:
Map jsonFileContent = json.decode(jsonFile.readAsStringSync());
Since you are trowing the generic part away. Instead it should be:
Map<String, dynamic> jsonFileContent = json.decode(jsonFile.readAsStringSync());
Or let Dart handle that stuff with:
final jsonFileContent = json.decode(jsonFile.readAsStringSync());
Upvotes: 1