How to write a map to a YAML file in Dart How to write a map to a YAML file in Dart dart dart

How to write a map to a YAML file in Dart


package:yaml does not have YAML writing features. You may have to look for another package that does that – or write your own.

As as stopgap, remember JSON is valid YAML, so you can always write out JSON to a .yaml file and it should work with any YAML parser.


It's a bit late of a response but for anyone else looking at this question I have written this class. It may not be perfect but it works for what I'm doing and I haven't found anything wrong with it yet. Might make it a package eventually after writing tests.

class YamlWriter {  /// The amount of spaces for each level.  final int spaces;  /// Initialize the writer with the amount of [spaces] per level.  YamlWriter({    this.spaces = 2,  });  /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List].  String write(dynamic yaml) {    return _writeInternal(yaml).trim();  }  /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List].  String _writeInternal(dynamic yaml, { int indent = 0 }) {    String str = '';    if (yaml is List) {      str += _writeList(yaml, indent: indent);    } else if (yaml is Map) {      str += _writeMap(yaml, indent: indent);    } else if (yaml is String) {      str += "\"${yaml.replaceAll("\"", "\\\"")}\"";    } else {      str += yaml.toString();    }    return str;  }  /// Write a list to a YAML string.  /// Pass the list in as [yaml] and indent it to the [indent] level.  String _writeList(List yaml, { int indent = 0 }) {    String str = '\n';    for (var item in yaml) {      str += "${_indent(indent)}- ${_writeInternal(item, indent: indent + 1)}\n";    }    return str;  }  /// Write a map to a YAML string.  /// Pass the map in as [yaml] and indent it to the [indent] level.  String _writeMap(Map yaml, { int indent = 0 }) {    String str = '\n';    for (var key in yaml.keys) {      var value = yaml[key];      str += "${_indent(indent)}${key.toString()}: ${_writeInternal(value, indent: indent + 1)}\n";    }    return str;  }  /// Create an indented string for the level with the spaces config.  /// [indent] is the level of indent whereas [spaces] is the  /// amount of spaces that the string should be indented by.  String _indent(int indent) {    return ''.padLeft(indent * spaces, ' ');  }}

Usage:

final writer = YamlWriter();String yaml = writer.write({  'string': 'Foo',  'int': 1,  'double': 3.14,  'boolean': true,  'list': [    'Item One',    'Item Two',    true,    'Item Four',  ],  'map': {    'foo': 'bar',    'list': ['Foo', 'Bar'],  },});File file = File('/path/to/file.yaml');file.createSync();file.writeAsStringSync(yaml);

Output:

string: "Foo"int: 1double: 3.14boolean: truelist:   - "Item One"  - "Item Two"  - true  - "Item Four"map:   foo: "bar"  list:     - "Foo"    - "Bar"


I ran into the same issue and ended up hacking together a simple writer:

  // Save the updated configuration settings to the config file  void saveConfig() {    var file = _configFile;    // truncate existing configuration    file.writeAsStringSync('');    // Write out new YAML document from JSON map    final config = configToJson();    config.forEach((key, value) {      if (value is Map) {        file.writeAsStringSync('\n$key:\n', mode: FileMode.writeOnlyAppend);        value.forEach((subkey, subvalue) {          file.writeAsStringSync('  $subkey: $subvalue\n',              mode: FileMode.writeOnlyAppend);        });      } else {        file.writeAsStringSync('$key: $value\n',            mode: FileMode.writeOnlyAppend);      }    });  }