aleskva
aleskva

Reputation: 1825

How to load Yaml file to the Map in Dart?

I know the Yaml library from Pub, which can load and parse Yaml string through loadYaml() function. But I don't know, how to load content of the Yaml file as the parameter of this function.

My Code (isn't working):

data.yaml

name1: thing1
name2: thing2

process.dart

import 'dart:html';
import 'package:yaml/yaml.dart';

main(){
String path = 'data.yaml';
return HttpRequest.getString(path)
    .then((String yamlString){
        YamlMap map = loadYaml(yamlString);
        String name = map['name1'];
        print(name);
    });    
}

Upvotes: 4

Views: 2743

Answers (3)

abd alqader najjar
abd alqader najjar

Reputation: 1

for me what I have is a List

- type: web
  features:
    - procurement
    - accounting
  notificationMessage:
    en: All Inventory services will be under maintenance. Sorry for inconvenience
    ar:  # 'ar' is optional
  startDate: '2024-02-02T19:30:00.835Z'
  endDate: '2024-02-05T18:45:00.835Z'

- type: mobile
  features:
    - procurement
    - accounting
    - inventory
  notificationMessage:
    en: All Inventory services will be under maintenance. Sorry for inconvenience
    ar:  # 'ar' is optional
  startDate: '2024-02-02T19:30:00.835Z'
  endDate: '2024-02-05T18:45:00.835Z'

so I generalized the solution to handle both YamlMap and YamlList types in a more flexible manner.

extension YamlMapConverter on YamlMap {
  dynamic _convertNode(dynamic v) {
    if (v is YamlMap) {
      return _convertYamlMap(v);
    } else if (v is YamlList) {
      return _convertYamlList(v);
    } else if (v is YamlScalar) {
      return v.value;
    } else {
      return v;
    }
  }

  Map<String, dynamic> _convertYamlMap(YamlMap yamlMap) {
    var map = <String, dynamic>{};
    yamlMap.nodes.forEach((key, value) {
      if (key is YamlScalar) {
        map[key.value.toString()] = _convertNode(value);
      }
    });
    return map;
  }

  List<dynamic> _convertYamlList(YamlList yamlList) {
    var list = <dynamic>[];
    for (var item in yamlList) {
      list.add(_convertNode(item));
    }
    return list;
  }

  Map<String, dynamic> toMap() {
    return _convertYamlMap(this);
  }
}

extension YamlListConverter on YamlList {
  dynamic _convertNode(dynamic v) {
    if (v is YamlMap) {
      return (v).toMap();
    } else if (v is YamlList) {
      return _convertYamlList(v);
    } else {
      return v;
    }
  }

  List<dynamic> _convertYamlList(YamlList yamlList) {
    var list = <dynamic>[];
    for (var item in yamlList) {
      list.add(_convertNode(item));
    }
    return list;
  }

  List<T> toYamlList<T>() {
    var list = <T>[];
    for (var item in this) {
      list.add(_convertNode(item));
    }
    return list;
  }
}

Simple Usage:

 final yamlString = response.data;
    YamlList yamlList = loadYaml(yamlString);

    final List<Map<String, dynamic>> list =
        yamlList.toYamlList<Map<String, dynamic>>();

Upvotes: 0

user1738833
user1738833

Reputation: 339

I'd imagine that to be watertight, the code below needs a little more work, but this is working for my basic purposes where I transitioned from JSON to YAML and wanted to retain the remainder of my codebase almost unchanged.

import 'package:yaml/yaml.dart';

extension YamlMapConverter on YamlMap {
  dynamic _convertNode(dynamic v) {
    if (v is YamlMap) {
      return (v as YamlMap).toMap();
    }
    else if (v is YamlList) {
      var list = <dynamic>[];
      v.forEach((e) { list.add(_convertNode(e)); });
      return list;
    }
    else {
      return v;
    }
  }

  Map<String, dynamic> toMap() {
    var map = <String, dynamic>{};
    this.nodes.forEach((k, v) {
      map[(k as YamlScalar).value.toString()] = _convertNode(v.value);
    });
    return map;
  }
}

...
var yamlData = loadYaml(yaml);
Map<String, dynamic> dartMap = yamlMap.toMap();
...

To become watertight, it would need to handle exceptions better and also handle items like YAML tags. I haven't needed these so I haven't developed it further.

Code based on Dart-YAML version ^3.1.0

Upvotes: 3

Tesseract
Tesseract

Reputation: 8139

Look at the source of loadYaml in yaml.dart. If you use eclipse or the DartEditor you can also just hover your mouse over loadYaml to get a description. It says there that if the function returns a map it's a YamlMap, not a normal Dart map. It may also return something else e.g. String, num, List. Why don't you just do a print(map) or print(map.runtimeType)?

Upvotes: 2

Related Questions