Dart FileUpdater works only on one field

Viewed 34

I have this piece of code that should update a .plist file

Future<String> getJsonAsString() async{
  var config = File('my_file.json');
  var stringContents = await config.readAsString();
  return stringContents;
}

Future<void> updateFields() async {
  var data = jsonDecode(await getJsonAsString());
  FileUpdater.updateFile(
    File('file.plist'),
    Plist(
      'field1',
      data['field1'],
    ),
  );
  FileUpdater.updateFile(
    File('file.plist'),
    Plist(
      'field2',
      data['field2'],
    ),
  );
}

my_file.json is a very simple json file with no nested data, like this:

{"field1": "value1", "field2": "value2"}

and file.plist is structured like this:

...
        <key>field1</key>
        <string>some_value1</string>
        <key>field2</key>
        <string>some_value2</string>
...

When I run my code, what I obtain is that only some_value2 is changed and becomes value2, while filed1 still have some_value1, like this:

...
        <key>field1</key>
        <string>some_value1</string>
        <key>field2</key>
        <string>value2</string>
...

If I delete the second FileUpdater, field1 is correctly updated. Is there something wrong in my code that I can't see?

1 Answers

It's not working as expected because the updateFile() method is an async method.

In your code, you're not using the await keyword when calling this method, so basically you're asking it to perform a second update before the first update has even begun, in which case (I don't know their exact implementation), it probably discards the first request.

If you use the await keyword:

Future<void> updateFields() async {
  var data = jsonDecode(await getJsonAsString());
  await FileUpdater.updateFile(
    File('file.plist'),
    Plist(
      'field1',
      data['field1'],
    ),
  );
  await FileUpdater.updateFile(
    File('file.plist'),
    Plist(
      'field2',
      data['field2'],
    ),
  );
}

Then it should work, because the edits will be done one-at-a-time.

Note: Just because a method is async doesn't mean you have to always use await -- In this case, the await keyword is only absolutely required on the first call (because there will be a subsequent call), so it's not absolutely necessary to use it on the second/last call... but I changed both because it's probably better/safer to just always use it.

Related