PDA

View Full Version : DB.getValue(node, [subpath [, default]]) returns nil if no subpath entry found, or?



Varsuuk
June 30th, 2023, 15:53
I went to combine various components across 3 comboboxes. The idea if you choose a race in the combobox, it invalidates sub/half-race combos (assuming it changed) and populates the next one down with proper sub or half-races.
This worked fine. So I went to add code to populate the "Race" box on the header.

EDIT: Clarification of the TLDR; question:
I always understood "getValue" would return nil of the node was not found, or the default specified if you passed that. But I am not passing a 3rd argument and still getting "", instead of the nil I expected, back on these strings - AS FAR AS I CAN SEE anyway...



function getValue(sourcenode, [subpath], [default])
Returns the value contained in the specified database node. The return value(s) vary depending on the type of the node. If the node does not exist or if the node is a non-value type, then the default values passed in will be returned or nil if no default values are specified.


When I was seeing the Race field fill with "()", I thought the only way that is possible is if the 2 or 3 values were non-nil. But... the first time, they have to be nil (because there are no nodes for subrace/halfrace yet) I verified this with /save and looking at the DB.
So I added the prints and saw what looked like "" values returned vs string

New log:


[6/30/2023 10:19:06 AM] s'updateRace' | databasenode = { charsheet.id-00004 }
[6/30/2023 10:19:06 AM] s'Race:' | s''
[6/30/2023 10:19:06 AM] s'Subrace:' | s''
[6/30/2023 10:19:06 AM] s'Halface:' | s''
[6/30/2023 10:19:06 AM] s'formatRaceString' | s'' | s'' | s''
[6/30/2023 10:19:06 AM] s' ()'
[6/30/2023 10:19:06 AM] s'updateRace' | databasenode = { charsheet.id-00004 }
[6/30/2023 10:19:06 AM] s'Race:' | s'Elf'
[6/30/2023 10:19:06 AM] s'Subrace:' | s''
[6/30/2023 10:19:06 AM] s'Halface:' | s''
[6/30/2023 10:19:06 AM] s'formatRaceString' | s'Elf' | s'' | s''
[6/30/2023 10:19:06 AM] s' ()'


This is what it looks like in the DB after selecting Elf on combo but the other 2 are still empty:


<race>
<baserace type="string">Elf</baserace>
<racevalue type="string">elf</racevalue>
</race>

(EDIT: After seeing it saves as "baserace" and "racevalue" I made the "source" property match the "name" so the autonaming in combobox would be consistant, the nodes are now "baserace" and "baseracevalue", it doesn't affect it but in case this was misleading)


Code to generate:


...
local nodeChar = getDatabaseNode()
Debug.console("updateRace", nodeChar)
Debug.console("Race:", DB.getValue(nodeChar, "race.baserace"))
Debug.console("Subrace:", DB.getValue(nodeChar, "race.subrace"))
Debug.console("Halface:", DB.getValue(nodeChar, "race.halfrace"))

local race_display = Race.formatRaceString(
DB.getValue(nodeChar, "race.baserace"),
DB.getValue(nodeChar, "race.subrace"),
DB.getValue(nodeChar, "race.halfrace"))

Debug.console(race_display)
DB.setValue(nodeChar, "race_string", "string", race_display)
...


The formatting thing (changing it to: if xxx == "" worked and proper string is generated. But...?)


function formatRaceString(race, subrace, halfrace)
Debug.console("formatRaceString", race, subrace, halfrace)
if race == nil then
return ""
end

if subrace == nil then
return race
elseif halfrace == nil then
return subrace
else
return subrace .. " (" .. halfrace .. ")"
end
end


Bonus Question:
Is there an opinion on "Best practices"? If the popup was a modal dialog (something which I will look to see if there is an option in what I open, I seem to recall seeing this before...), I'd simply do the RACE update on "onClose()". I currently do it on the onValueChanged() of any of the 3 race subfields since the user can leave that window open - again, I suspect that is my FIRST problem - picking wrong option there and I will fix it if there is a modal version to use, but still worth asking. Or is it OK to add a "button" to "Apply" changes or "Cancel" as it were and do the caculation/string-concat there?

Moon Wizard
June 30th, 2023, 18:54
I'm not sure of the specific issue with DB.getValue without a simple extension that shows the issue that I can test with (i.e. remove all extraneous data and just show the error).

In general, I tend to write empty checks on string/nil data like this:
if (s or "") ~= "" then
....
end

Regards,
JPG

Varsuuk
June 30th, 2023, 20:14
I'm not sure of the specific issue with DB.getValue without a simple extension that shows the issue that I can test with (i.e. remove all extraneous data and just show the error).

In general, I tend to write empty checks on string/nil data like this:
if (s or "") ~= "" then
....
end

Regards,
JPG

OK - I wanted to make sure the documentation was correct (which I expect, since nil IS the obvious "not there" value to use) as a sanity check.
I'll continue with accepting "" as same as nil since for my purposes it is ;). And I'll try to recreate it (and probably in the process find out WHY it was behaving wrong when it behaves right and I start slowly building back to what I did... I just don't SEE why it isn't returning nil!!! frustrating, if nil is the default, then I am certain it is something I did and didn't see - maybe now that I know it HAS to return nil, I'll be able to see the issue)