How to modify a JSON object that's been read in?

I have read a JSON using JSON3.jl but after that I can’t seem to modify the json.

E.g.

a = JSON3.read("{\"a\":1}")

a[:b] = 2

what I get is this.

Is there an easy to mutate the object?

LoadError: MethodError: no method matching setindex!(::JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}}, ::Int64, ::Symbol)
e[0mClosest candidates are:
e[0m  setindex!(::AbstractDict, ::Any, ::Any, e[91m::Anye[39m, e[91m::Any...e[39m) at abstractdict.jl:505
MethodError: no method matching setindex!(::JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}}, ::Int64, ::Symbol)
Closest candidates are:
  setindex!(::AbstractDict, ::Any, ::Any, ::Any, ::Any...) at abstractdict.jl:505

Stacktrace:
 [1] top-level scope
   @ In[139]:3
 [2] eval
   @ ./boot.jl:360 [inlined]
 [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1094

As per the docs:

The JSON3.Object supports the AbstractDict interface, but is read-only (it represents a view into the JSON source input), thus it supports obj[:x] and obj["x"] , as well as obj.x for accessing fields. It supports keys(obj) to see available keys in the object structure. You can call length(obj) to see how many key-value pairs there are, and it iterates (k, v) pairs like a normal Dict . It also supports the regular get(obj, key, default) family of methods.

The JSON3.Array{T} supports the AbstractArray interface, but like JSON3.Object is a view into the input JSON, hence is read-only. It supports normal array methods like length(A) , size(A) , iteration, and A[i] getindex methods.

If you really need Dict s and Vector s, then you can use copy(x) to recursively convert JSON3.Object s to Dict s and JSON3.Array s to Vector s.

2 Likes

Just use copy to turn it into something mutable

using JSON3
a = JSON3.read("{\"a\":1}")

a = copy(a)

a[:b] = 2
2 Likes