leafo / lapis

A web framework for Lua and OpenResty written in MoonScript
http://leafo.net/lapis/
MIT License
3.12k stars 247 forks source link

Always return nil columns in a JSON response? #658

Closed cycomachead closed 4 years ago

cycomachead commented 5 years ago

It seems that if I just return an object using json = that nil/null values don’t end up in the response.

Is there a good way around this? Thanks!

karai17 commented 4 years ago

A late answer, but someone else may stumble on this in the future. Lua treats nil as "no value" unlike other languages where NULL is a legitimate data type. Anything with a value of nil will simply be removed, or perhaps it is more correct to say that it does not exist in the first place.

local t = {
  "aaa",
  "sss",
  nil, -- this doesn't actually exist!
  "fff"
}
for i, v in ipairs(t) do
  print(i, v) -- [1 aaa, 2 sss] you will note it does not go past 2 because 3 doesn't exist and so ipairs considers the length of this table to be 2
end

The only caveat to that is that you can declare a variable without a value to place that variable into a specific block scope:

local n = 5
local m -- declaring local m inside the if or the else would cause the print to error out. erasing this line woudl cause m to be declared as global instead of erroring
if n >= 5 then
  m = 7
else
  m = 9
end

print(n+m) -- prints 12

So when you return an object that would have keys with nil values, those keys cease to exist so they cannot be sent. You would need to add in a "null equivalent" value that the receiver of the data can decode. Lapis' database models have a db.NULL value that models know how to replace for a NULL sql value, for example.

leafo commented 4 years ago

If you need json null or a empty array you can use the following constants provided by the cjson library since lua does not have equivalent values:

local cjson = require "cjson"

csjon.null --> null

cjson.empty_array --> []
cycomachead commented 4 years ago

I forget how I worked around this, but thank you! that's good to know.