Guidance for type conversions
Guidance for type conversions
We're using DataTables and Editor with a custom AJAX back-end and we are confused about when and where we should do type conversions from the back-end to Editor forms and back.
Suppose that an AJAX response contains this value:
{
"name": "Tiger Nixon",
"salary": 320800
}
Is this a good columns config?
columns: [
{ data: "name" },
{ data: "salary", render: $.fn.dataTable.render.number(",", ".", 0, "$") }
]
Is this a good fields config?
fields: [
{
name: "name",
label: "Name",
type: "text"
},
{
name: "salary",
label: "Salary",
type: "text",
attr: {
type: "number"
}
},
]
This renders two input fields in the form.
in pseudo markup:
<input type="text" name="name">
<input type="number" name="salary">
I get mentally stuck on the salary field. All salaries flowing from the back-end to the Editor form are numeric up until the point where they are rendered in the HTML.
<input type="number" name="salary" value="320800">
Any changes to the salary field are naturally submitted as string (since <input> values are always strings).
Now I have a few options where I can convert that value back to a number: inside a preSubmit
handler or inside ajax
(as a function) or inside a postSubmit
handler. The choices are a little overwhelming.
Is there a good place where I can convert values from strings back to their expected type? Or should I use strings everywhere in DataTables/Editor and handle conversions in the data layer of my app?
Replies
I'm not sure if it's the correct way but in my app that uses a Java/Spring REST backend handles any type coming from the client side. This REST layer then turns the JSON into Objects, it's at this point they are converted to their expected types. These Objects are then suitable for the Service Layer.
Layers: Client Side <-> (ServerSide: REST <-> Service <-> Data)
This way our server side is less flaky depending on the client implementing the correct types. The REST layer is purely for REST. The Service layer implements the business logic. The aim of this is the application is not tightly coupled to REST and the server side is quite resilient to errors in client json packets.
preSubmit
andajax.data
are more or less the same thing - either can be used to modify the data that is sent to the server.If you are submitting the data as HTTP parameters (which Editor does by default) then type conversion would need to be done at the server-side. If you are submitting it as JSON in the request body, then it is really up to yourself if you do it client-side or server-side.
Allan
I decided to convert all values to string before they go into the table. That makes Ajax sourced tables behave the same as DOM sourced tables.
When DataTables calls
ajax
as a function for the first time on page load, I get a snapshot of strongly-typed data from our custom back-end and convert all values to string before passing the stringly-typed snapshot to thesuccess(json)
callback function.When Editor raises
preSubmit
, I parse all changed fields from string to their expected type so I can validate them. This is an uglyswitch
statement that maps field names to parse functions.When Editor raises
postSubmit
, I parse all changed fields again so I can queue them in an event log. The event log is an array of objects that describe what has changed.When DataTables calls
ajax
as a function again, I replay the event log on the snapshot before converting all values to string again.(There is a button that submits the event log to the server where it is used to update the persistent data).
It's a complicated setup an unfortunately it's very fragile and high maintenance code. I wish this part was easier.
If I were to introduce a new parameter to the field which would let you set the Javascript data type (i.e. number, string, etc) as the value is read back from the input field, would that resolve the issue? I've been thinking about doing that anyway.
Allan
Would it be possible to configure a callback for the option? I think that would be a big improvement.
Are you thinking that would run inside
val()
(i.e. it would get the value and then format it viaparseInput
- even although that could result in a significantly different value, such as in the moment example), or only as part of the data submission?Allan
It would run as soon as possible after a form is submitted, before change detection.
I have had problems when I feed a table with integers:
After opening and closing Editor (but without changing the value) it comes back as a string.
This is a problem because Editor detects this as a changed value and fires the whole chain of
submit
events. That's when it's too late to run theparseInput
callback.The bright side of this is that Editor doesn't coerce type when detecting changes. I like that a lot. It just needs an extension point for us to convert the value to the correct type before change detection runs.
Check out this, I used it to solve similar problem.
You also can have cloud hosting company to solve such problems for you.