When it comes to functional programming, the practice is to create a new object with added key-value pairs instead of reassigning values.
It's important to note that immutability isn't solely tied to functional programming. However, based on your statement, I assume you want 'emptyObj' to remain unchanged while creating a separate object 'test' with specific properties like 'key1' and 'key2'.
The issue here is not about object usage conflicting with functional programming principles, but rather about the limitations of objects as dictionaries. In such cases, using Maps would be more appropriate. Maps function as true dictionaries and offer handy tools for manipulation with less cognitive strain.
const Box=(x)=>({
map: (key,value)=>Box((new Map(x).set(key,value))),
clear: (key,value)=>Box((copy=>(copy.delete(key),copy))(new Map(x))
),
fold: f=>f(new Map(x)), // EDITED to prevent leaking the original map
})
const formData=obj=>(
Box(obj)
.map('key1',document.getElementById("value1").value)
.map('key2',document.getElementById("value2").value)
.fold(s=>s)
)
const clearData=obj=>(
Box(obj)
.clear('key1')
.clear('key2')
.fold(s=>s)
)
const emptyObj=new Map()
const test1=formData(emptyObj)
const test2=clearData(test1)
console.log(emptyObj) // empty
console.log(test1) // both keys
console.log(test2) // empty again
Incorporating additional features like the capability to immutably 'clear' data alongside 'map' operations exemplifies how straightforward this process can be. A particular syntax was utilized in the 'clear' method due to the behavior of Map.prototype.delete
.
If delving into immutability without strictly adhering to functional programming, various immutable class libraries are accessible in JavaScript that offer immutable Maps or the option to subclass one easily.
EDIT
An update from the original post mentions the necessity of working with objects for JSON communication purposes. One easy workaround involves utilizing a helper function to convert Maps to JSON:
let map=new Map([['key1','value1'],['key2','value2']])
const mapToJson=map=>(
'{'+
[...map].map(([key,value])=>(
'"'+key+'":'+(value===undefined ? 'null' : JSON.stringify(value)))
).join(',')+
'}'
)
console.log(mapToJson(map)) // {"key1":"value1","key2":"value2"}
A special precaution had to be taken for checking 'undefined' since the JSON format recognizes only 'null' for undefined values, not the string representation 'undefined'.
This solution assumes the use of string keys in Maps, hence error checks can be implemented for scenarios involving other types of keys.