Monaco-editor: Set schema of JSON content without $schema property

Created on 15 Sep 2016  路  5Comments  路  Source: microsoft/monaco-editor

In monaco-json, it is possible to assign json schemas (for validation and code hints) to json files (file-names), however when running monaco stand alone in a browser, I don't have any filenames.

How can I select a schema to use for a json editor instance?

Using the $schema property works in theory, but gives problems if the schema doesn't allow this property in the root scope. See the following example modified from the Monaco Editor Playground JSON example:

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [{
        uri: "http://myserver/foo-schema.json",
        schema: {
            properties: {
                p1: {}
            },
            additionalProperties: false
        }
    }]
});

var jsonCode = [
    '{',
    '    "$schema": "http://myserver/foo-schema.json"',
    "}"
].join('\n');

monaco.editor.create(document.getElementById("container"), {
    value: jsonCode,
    language: "json"
});

2016-09-15_16-12-08

monaco-editor npm version: 0.6.1
Browser: All
OS: All

Most helpful comment

Here's a example on how to do it. In the file match you can also use patterns like *.json, or foo*.json.
You can make up any model URI you want, it's just used as an identifier.

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    schemas: [{
      fileMatch: ['foo.json'],
      schema: {
            type: "object",
            properties: {
                p1: {
                    enum: [ "v1", "v2"]
                }
            }
        }
    }]
});


var jsonCode = [
    '{',
    "}"
].join('\n');

var model = monaco.editor.createModel(jsonCode, 'json', 'internal://server/foo.json');

monaco.editor.create(document.getElementById("container"), {
    model: model
});

All 5 comments

I am sorry that we don't have a proper tutorial explaining models, editors, and languages. I plan to write one as soon as I get some breathing time :).

The gist is:

  • you can create editors via monaco.editor.create(..). Don't forget to dispose them.
  • you can create models (buffers) via monaco.model.create(..). Don't forget to dispose them.
  • one editor can have one or no model. i.e. editor.setModel(model), editor.setModel(null).
  • a model can be detached from all editors, can be attached to one editor, or to more editors at the same time.

For the 90% use-case where things are simple, we have added the "implicit" model concept. If you create an editor you can pass in a value and a language and the editor will create a model for you and will dispose it for you. Makes the easy use-case simple.

However, an editor can also be constructed with model: null or model: model where model is pointing to a model created via monaco.editor.createModel, in which case it will not create an "implicit" auto-managed model. The createModel call accepts an uri that is used as an identifier of the model (must be unique across all alive models).

Ok, that was the theoretical part. I'm not the JSON expert (@aeschli is) but I think you can use the fileMatch property next to the uri of the schema and write that in a way that it matches the uri you use when you create a model via monaco.editor.createModel.

Here's a example on how to do it. In the file match you can also use patterns like *.json, or foo*.json.
You can make up any model URI you want, it's just used as an identifier.

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    schemas: [{
      fileMatch: ['foo.json'],
      schema: {
            type: "object",
            properties: {
                p1: {
                    enum: [ "v1", "v2"]
                }
            }
        }
    }]
});


var jsonCode = [
    '{',
    "}"
].join('\n');

var model = monaco.editor.createModel(jsonCode, 'json', 'internal://server/foo.json');

monaco.editor.create(document.getElementById("container"), {
    model: model
});

@aeschli Thanks for the explanation. I couldn't find the information about the name as identifier before.

@aeschli Thanks for the sample.
Please add uri as parameter while defining schema as mentioned here.
When there are multiple schemas; if you don't specify uri, monaco editor will pick last schema added to schemas array.

@apalsapure ,

If we do not specify URI, then will it take last schema ?
I added following code, but schema is not reflected in editor:

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    schemas: [{
      schema: {
            type: "object",
            properties: {
                p1: {
                    enum: [ "v1", "v2"]
                }
            }
        }
    }]
});


var jsonCode = [
    '{',
    "}"
].join('\n');

var model = monaco.editor.createModel(jsonCode, 'json');
monaco.editor.setModelLanguage()

monaco.editor.create(document.getElementById("container"), {
    model: model
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

galyech picture galyech  路  3Comments

Panhaiwei picture Panhaiwei  路  3Comments

SoftTimur picture SoftTimur  路  3Comments

inf9144 picture inf9144  路  3Comments

robclive picture robclive  路  3Comments