Guidance for type conversions

Guidance for type conversions

sliekenssliekens Posts: 97Questions: 17Answers: 2

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

  • rduncecbrduncecb Posts: 109Questions: 2Answers: 22

    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.

  • allanallan Posts: 43,557Questions: 1Answers: 5,703 Site admin

    preSubmit and ajax.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

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    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 the success(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 ugly switch 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.

  • allanallan Posts: 43,557Questions: 1Answers: 5,703 Site admin

    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

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    Would it be possible to configure a callback for the option? I think that would be a big improvement.

    fields: [
      {
        name: "salary",
        label: "Salary",
        type: "text",
        parseInput: function(text) { return parseInt(text, 10); }
      },
      {
        name: "start_date",
        label: "Start Date",
        type: "text",
        parseInput: function(text) { return moment(text); }
      }
    ]
    
  • allanallan Posts: 43,557Questions: 1Answers: 5,703 Site admin

    Are you thinking that would run inside val() (i.e. it would get the value and then format it via parseInput - 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

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    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:

    { salary: 50000 }
    

    After opening and closing Editor (but without changing the value) it comes back as a string.

    { salary: "50000" }
    

    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 the parseInput 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.

Sign In or Register to comment.