How do I parse a JSON string in EK9?

← JSON and Data Processing · Ref: Q190

Parse with the instance method parse(): JSON().parse(text) returns a Result of (JSON, String) - the parsed JSON on success, an error message when the text is not valid JSON. Check isOk() before ok(). Access properties with .get(key) for objects and .get(index) for arrays. Iterate with .iterator().

PARSING JSON STRINGS

  parseResult <- JSON().parse(`{"name": "Alice", "age": 30}`)
  if parseResult.isOk()
    person <- parseResult.ok()
    stdout.println($person)

Calling ok() without the isOk() check is E08030. Note the JSON(String) CONSTRUCTOR does not parse: it makes a JSON string value holding the text (objectNature() is false).

ACCESSING PROPERTIES

Use .get(key) to access object properties:

  name <- parsed.get("name")

Use .get(index) to access array elements:

  first <- jsonArray.get(0)

NATURE CHECKS

Check what kind of JSON value you have:

  parsed.objectNature()  true for JSON objects
  parsed.arrayNature()   true for JSON arrays
  parsed.valueNature()   true for primitives

ITERATION

Iterate over JSON arrays or object entries:

  for item in parsed.iterator()
    stdout.println($item)

See Q188 for JSON as a first-class type. See Q48 for Result type. See Q29 for unset variables.

Example

defines module qa.jsonparsed.parsing

  defines program

    JsonParsingDemo()
      stdout <- Stdout()

      // === PARSING JSON STRINGS ===
      // parse() is an instance method that returns Result of (JSON, String)

      objectResult <- JSON().parse(`{"name": "Alice", "age": 30}`)
      if objectResult.isOk()
        parsed <- objectResult.ok()
        stdout.println(`Parsed JSON: ${parsed}`)

        // === ACCESSING PROPERTIES ===

        nameJson <- parsed.get("name")
        stdout.println(`Name: ${nameJson}`)

        ageJson <- parsed.get("age")
        stdout.println(`Age: ${ageJson}`)

        // === NATURE CHECKS ===

        stdout.println(`Is object: ${parsed.objectNature()}`)
        stdout.println(`Is value: ${parsed.valueNature()}`)

      // === JSON ARRAYS ===

      arrayResult <- JSON().parse(`[10, 20, 30]`)
      if arrayResult.isOk()
        arr <- arrayResult.ok()
        stdout.println(`Array: ${arr}`)
        stdout.println(`Is array: ${arr.arrayNature()}`)

        firstItem <- arr.get(0)
        stdout.println(`First item: ${firstItem}`)

        // === ITERATION ===

        for item in arr.iterator()
          stdout.println(`Item: ${item}`)

      // === INVALID TEXT GIVES AN ERROR, NOT AN EXCEPTION ===

      badResult <- JSON().parse("not json")
      stdout.println(`Invalid text is ok: ${badResult.isOk()}`)

      // === THE CONSTRUCTOR DOES NOT PARSE ===
      // JSON(String) makes a JSON string VALUE holding the text

      wrapped <- JSON(`{"name": "Alice"}`)
      stdout.println(`Constructor gives object: ${wrapped.objectNature()}`)

Common mistakes

E50060 — The JSON type does not have 'getString()', 'getInt()', or similar typed accessor methods. Use '.get(key)' for object properties and '.get(index)' for array elements. The result is always a JSON value. See ek9 -h E50060 for details.

Incorrect:

nameJson <- parsed.getString("name")

Correct:

nameJson <- parsed.get("name")
Other ways to ask this
  • How do I create JSON from a string in EK9?
  • How do I access JSON properties in EK9?
  • How do I read JSON data in EK9?

Coming from another language?

Java: Jackson ObjectMapper.readTree() for tree model, readValue() for POJO binding. Python: json.loads() to dict. Rust: serde_json::from_str(). Go: json.Unmarshal(). Kotlin: kotlinx.serialization Json.decodeFromString(). EK9: JSON().parse(text) returns a Result of (JSON, String) - no exceptions, the compiler makes you check isOk() - then .get() for property access, .iterator() for traversal.

Keywords: serialize, json, get, parse, null, property, access, data, string, result, iterate, error, guard, ok