Nullable boolean values in JSON


#1

Hi Sebastian,

I have several checkboxes in one of my schemas and I am trying to map those in JSON so that the value in the JSON is either null, true or false.

Currently I’m only getting true or false back even though for some pages the checkbox value is set to its default (a dash inside of the checkbox input control UI).

To explain further; I have a HTML table with some products.
Each row is a product.
Each product has a bunch of properties.
One of those properties is called HasAirHoles (bool/checkbox)
In the table cell for that property any of the following values should be displayed: “Missing info” (null - the user has not interacted with the checkbox yet in the editorial UI), “Yes” (true), “No” (false).

So as you can see I need that null value in the JSON object.

I’ve been looking into the InvariantConverter and HttpClientExtensions classes in the ClientLibrary but haven’t been able to figure out exactly how everything works and where to make modifications. Got any ideas?


#2

If you use a boolean field which is not set to required it allows null or not set. But there are no controls yet, that support it. They start with an undefined state (= null or not set) and then you can only go to true or false, but not back to undefined. This is probably something for a feature request.

The invariantconverter has nothing to do with it, it just simplifies using “non-localized” fields. Instead of a nested structure

field: {
  iv: value
}

You can model your entities as if would be a flat structure

field: value

#3

What do you mean by “Instead of a nested structure” "You can model your entities as if would be a flat structure

" ?


#4

By default you will get the following json back:

{
   data: {
      firstName: {
          iv: Sebastian
      }
   }
}

If you want to map this to a class in C# you have several options, here are some simplified examples:

class User {
   UserData Data;
}

// Alternative 1:
class UserData {
   Dictionary<string, string> FirstName
}

// Alternative 2:
class InvariantValue<T>
{
    [JsonProperty("iv")]
    T Value;
}

class UserData {
   InvariantValue<string> FirstName
}

// Alternative 3:
class UserDataFirstName
{
    [JsonProperty("iv")]
    T Value;
}

class UserData {
   UserDataFirstName FirstName
}

But it is annoying to use.

// Alternative 1:
var firstName = user.Data.FirstName.Values.FirstOrDefault();
// Alternative 2:
var firstName = user.Data.FirstName.Value;
// Alternative 3:
var firstName = user.Data.FirstName.Value;

Therefore I use the InvariantConverter, you can just use: `

class User {
   UserData Data;
}

class UserData {
   [JsonConverter(typeof(InvariantConverter))]
   string FirstName
}

or with the base classes: https://github.com/Squidex/squidex-samples/blob/master/csharp/Sample.Profile/Sample.Profile/Models/Project.cs


#5

Not sure i follow and not sure how that would apply to my app.

But back to my first question. That feature request. Is it a lot of work? Or could I do some sort of workaround? One option would be to change the field from a bool to a string but then I’d manually have to update all records (100+)
Any ideas are welcome.


#6

It is not a lot of work. I can implement it for the toggle control.


#7

That would be great.


#8

I implemented deployed it for you. You have to press Ctrl or Shift when you click the toggle control to toggle between three states: null, true or false.


#9

Awesome! Will try it ASAP. Thanks!


#10

Does it work for you?


#11

Sorry been busy. Will check later today. I’ll let you know.


#12

Seems to be working now, Sebastian.
I changed my property from bool to bool? and now I can see null both in the VS (c#) and Chrome (javascript/json) debugger.
Much appreciated for the quick fix!