How do I process JSON data with stream pipelines in EK9?
← JSON and Data Processing · Ref: Q191
EK9 stream pipelines can extract typed values from JSON using 'collect as Type'. JSON values flow through pipelines and convert to target types automatically.
JSON TO TYPED VALUE
Extract a single typed value from JSON:
json <- List(JSON("val", JSON(2))) anInt <- cat json | collect as Integer
The pipeline extracts the integer value 2.
JSON ARRAY SUMMATION
Convert a list to JSON and sum via pipeline:
total <- cat $$ [4, 6, 18, 22] | collect as Integer
The $$ converts the list to JSON, pipeline sums as Integer.
JSON OBJECT PROPERTY SUMMATION
Parse a JSON object with JSON().parse(text), which returns a Result of (JSON, String), then sum its numeric properties:
objectResult <- JSON().parse(`{"a": 1, "b": null, "c": 22}`) if objectResult.isOk() total <- cat objectResult.ok() | collect as Integer stdout.println($total)
The total is 23: null values are skipped (they become unset in the tri-state model). The JSON(String) constructor does NOT parse - it makes a JSON string value, and summing that gives an unset result.
NULL HANDLING
JSON null becomes an unset value in EK9:
nullParse <- JSON().parse(`{"val": null}`) if nullParse.isOk() result <- cat List(nullParse.ok()) | collect as Integer stdout.println(`unset: ${not result?}`)
See Q188 for JSON basics. See Q59 for function pipelines. See Q122 for collect as.
Example
defines module qa.jsondata.streams defines program JsonStreamsDemo() stdout <- Stdout() // === JSON TO TYPED VALUE === json <- List(JSON("mainValue", JSON(2))) anInt <- cat json | collect as Integer stdout.println(`Extracted integer: ${anInt}`) // === JSON ARRAY SUMMATION === sumOfArray <- cat $$ [4, 6, 18, 22] | collect as Integer stdout.println(`Sum of array: ${sumOfArray}`) // === JSON OBJECT PROPERTY SUMMATION === // parse() returns Result of (JSON, String); the null property is skipped objectResult <- JSON().parse(`{"first": 1, "second": null, "third": 22}`) if objectResult.isOk() jsonObject <- objectResult.ok() sumOfProps <- cat jsonObject | collect as Integer stdout.println(`Sum of properties: ${sumOfProps}`) // === NULL HANDLING === // JSON null becomes unset in EK9's tri-state model nullParse <- JSON().parse(`{"mainValue": null}`) if nullParse.isOk() jsonWithNull <- List(nullParse.ok()) nullResult <- cat jsonWithNull | collect as Integer if not nullResult? stdout.println("JSON null became unset Integer") // === FLOAT EXTRACTION === jsonFloat <- List(JSON(2.88)) aFloat <- cat jsonFloat | collect as Float stdout.println(`Extracted float: ${aFloat}`)
Common mistakes
E50001 — parse() is an INSTANCE method, not a static one: call it on JSON() - JSON().parse(text) - and it returns a Result of (JSON, String). Check isOk() before ok() (an unguarded ok() is E08030). The JSON(String) constructor does not parse; it makes a JSON string value. See ek9 -h E50001 for details.
Incorrect:
objectResult <- JSON.parse(`{"first": 1, "second": null, "third": 22}`)
Correct:
objectResult <- JSON().parse(`{"first": 1, "second": null, "third": 22}`)
Other ways to ask this
- How do I extract typed values from JSON using streams?
- How do I sum JSON values with pipelines in EK9?
- How does collect as work with JSON in EK9?
Coming from another language?
Java: Jackson + Stream API for JSON processing, manual type extraction. Python: json.loads() + list comprehensions. Rust: serde_json + iterators. Go: json.Unmarshal to struct + range loops. EK9: JSON integrates with stream pipelines natively, 'collect as Type' extracts and aggregates typed values from JSON.
Keywords: sum, json, stream, extract, serialize, data, pipeline, convert, type, collect, aggregate