Huy Tran
Huy Tran

Reputation: 619

Can't parse YAML to JSON using yaml.js

I'm really new with Javascript so don't laugh too loud if this trouble is so easy. I must parse JSON Object to YAML & after that using new edited of YAML (which user will give us), parse it to JSON Object.
I choice yaml.js & json2yaml.js which wrote by same author.
Trouble is everything is fine when I parse from JSON Object to YAML. For instance, what json2yaml.js give me after parse is:

---
  state: 
    id: 0
    name: "CA"
    folder: 
      id: 1202
      name: "ABC"
    type: 
      typeName: "firstlevel"
      defaultthings: null
      mainType: "metropolis"
      id: 207
      name: "CA"
    owner: 
      id: 202
      name: null
    errorMessage: ""
    isError: false
  county: 
    - 
      id: 0
      name: "_1"
      folder: ""
      city: 
        Type: "urban"
        id: 17206
        name: "El Segundo"
      numberofinstances: 1
      errorMessage: ""
      isError: false

But when I parse it to JSON using yaml.js, I get error that can not parse the yaml file. I think it's because of wrong generate yaml function, but don't know how to work with this.
Does anybody face up with this, do you know any solution for this???

======
[Updated] Provide code snippet I use to parse From JSON to YAML

"use strict";             
 var YAML = window.YAML , json, data , yml;                             
 json = JSON.stringify(ko.toJS(finalData), null, 2);
 data = JSON.parse(json);            
 yml = YAML .stringify(data);
 return yml;

From YAML to JSON

var YAML = window.YAML, json, data;
data = YAML.parse(yml); // yml text we got above
json = JSON.stringify(data);
var jsonObject = JSON.parse(json);

Actually, I don't think it's syntax error, because of I used default code block on the website: http://jsontoyaml.com/#browser-javascript.

Upvotes: 2

Views: 5954

Answers (2)

composix
composix

Reputation: 11

Another fix is to move the indentation code (that was placed around the forEach) inside the forEach thereby reducing the indentation level. The firstLine check is then not needed.

The corrected source code can be found here. Note the identation code at lines 69 and 71 (for arrays), and 106 and 108 (for objects).

Working examples can be found here for NodeJS (requires login to run) and here for running in the browser:

<html>
<head>
    <title>YAML</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.10.0/js-yaml.min.js"
            type="text/javascript"></script>
    <script src="https://unpkg.com/[email protected]/dist/cpx-module_standalone.min.js"
            type="text/javascript"></script>
    <script src="https://rawgit.com/jeroenvalk/ComPosiX/master/src/main/javascript/modules/yaml.js"
            type="text/javascript"></script>
</head>
<body>
<table border="1">
    <tr>
        <td><strong>YAML<strong></td>
        <td><strong>JSON<strong></td>
    </tr>
    <tr>
        <td><pre id="yaml"></pre></td>
        <td><pre id="json"></pre></td>
    </tr>
</table>
<script type="text/javascript">
    _.module(['yaml'], function(YAML) {
        const yaml = YAML.stringify({
            "foo": "bar",
            "baz": ["qux", "quxx"],
            "corge": null,
            "grault": 1,
            "garply": true,
            "waldo": "false",
            "fred": "undefined"
        });
        document.getElementById('yaml').innerHTML = yaml;

        const json = JSON.stringify(jsyaml.load(yaml), null, 4);
        document.getElementById('json').innerHTML = json;
    });
</script>
</body>
</html>

Upvotes: 1

somallg
somallg

Reputation: 2043

It seems like the yaml's format is a little off (check with http://www.yamllint.com/), it shouldn't have an extra indentation after the --- marker. I take a look at the source code in json2yaml.js, the idenLevel is always '\s\s'

indentLevel = indentLevel.replace(/$/, '  ')

You don't need that, you would only need that if its not the first line (after the marker) To fix that, you can add below code at line 7 of json2yaml.js

var handlers, indentLevel = '', firstLine = true; // add firstLine check

Then at line 38 before x.forEach and line 69 before Object.keys(x).forEach, add this check

if (firstLine) {
    firstLine = false;
} else {
    indentLevel = indentLevel.replace(/$/, '  ')
}

Your yaml should be a valid one now, and can be parsed back to JSON. Hope that helps.

Upvotes: 1

Related Questions