Skip to content
Advertisement

How do I format JSON code in Monaco Editor with API?

I am working with monaco editor aka the VS Code engine in a web project.

I am using it to allow users to edit some JSON that has a JSON Schema set, to help give some auto-completion.

When they save their changes and wish to re-edit their work, the JSON that I load back into the editor is converted to a string but this renders the code out on a single line and I would much prefer the JSON to be prettier as if the user right clicks and uses the Format Document command from the context menu or keyboard shortcut etc..

So this

{ "enable": true, "description": "Something" }

Would become this

{
    "enable": true,
    "description:" "Something"
}

Current attempt

I have tried the following but it feels very hacky to use a timeout to wait/guess when the content has loaded

require(['vs/editor/editor.main'], function() {

  // JSON object we want to edit
  const jsonCode = [{
    "enabled": true,
    "description": "something"
  }];

  const modelUri = monaco.Uri.parse("json://grid/settings.json");
  const jsonModel = monaco.editor.createModel(JSON.stringify(jsonCode), "json", modelUri);

  const editor = monaco.editor.create(document.getElementById('container'), {
    model: jsonModel
  });

  // TODO: YUK see if we can remove timeout, as waiting for the model/content to be set is weird
  // Must be some nice native event?!
  // ALSO ITS SUPER JARRING WITH FLASH OF CHANGE
  setTimeout(function() {
    editor.getAction('editor.action.formatDocument').run();
  }, 100);

});
<script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.19.3/min/vs/loader.js"></script>
<script>
  require.config({
    paths: {
      'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.19.3/min/vs'
    }
  });
</script>

<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>

Does anyone have a better idea or solution to this please?

Advertisement

Answer

require(['vs/editor/editor.main'], function() {

  // JSON object we want to edit
  const jsonCode = [{
    "enabled": true,
    "description": "something"
  }];

  const modelUri = monaco.Uri.parse("json://grid/settings.json");
  const jsonModel = monaco.editor.createModel(JSON.stringify(jsonCode, null, 't'), "json", modelUri);

  const editor = monaco.editor.create(document.getElementById('container'), {
    model: jsonModel
  });
});
<script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.19.3/min/vs/loader.js"></script>
<script>
  require.config({
    paths: {
      'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.19.3/min/vs'
    }
  });
</script>

<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>

Thanks to https://stackoverflow.com/users/1378051/dalie for reminding me about the extra arguments to JSON.stringify

Answer

Use the tab character for the space argument
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

const jsonModel = monaco.editor.createModel(JSON.stringify(jsonCode, null, 't'), "json", modelUri);

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement