Android Question How to replace the null value of a label

Daniel44

Active Member
Licensed User
Hey everyone!

Im storing inside a map some double values... but when that values inside the map are null and I want to show in a label.text = 0,00 it shows me null... I mean If my map.size = 0 I need to show 0,00 on the label.text and I can't change that text

Here's my map

B4X:
account = parser.NextArray
    For i = 0 To account.Size - 1
    Dim m As Map
    m = account.Get(i)
If m.Size = 0 Then
LblValues.Text = "0,00 "

on my my devece lblValues shows me: null and I need it shows me 0,00

I've changed it to '00,0' then to 0 then to '0' I also created a varible to assign to the label with a 0,00 value but nothing happens.. it just still showing null. Thank you
 

Daniel44

Active Member
Licensed User
You don’t need the if/else. Only the 4 lines in the if portion. Get rid of of the rest (of what is quoted)

Oliver if I don't do that it won't show me the sum of the colum.. Here's the log when there's value to sum..

B4X:
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (gastos) Create, isFirst = true **
** Activity (gastos) Resume **
** Activity (gastos) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesC":"62112.55"}]
Response from server: [{"TotalesF":"100"}]
(MyMap) {TotalesF=100}
Response from server: [{"idfiado":"1","fechafiado":"2019-11-23 15:32:56","montofiado":"100","detallefiado":"varios"}]
(MyMap) {idfiado=1, fechafiado=2019-11-23 15:32:56, montofiado=100, detallefiado=varios}
 
Upvote 0

Daniel44

Active Member
Licensed User
Screenshot-20191123-152437.png
here's a screenshot when there's no values to sum

rsJWhzF
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
B4X:
Case TRAERTOTALFIADOS
                'NEW NEW - looks like you don't need to assign montofiado the Json2List result, since you are assigning it parser.NextArray below
                'Dim montofiado As List = Json2List(jobResult)
                Dim montofiado As List

                montofiado = parser.NextArray 'returns a list with maps
                For i = 0 To montofiado.Size - 1
                    Dim m As Map
                    m = montofiado.Get(i)
                    Log (m)
'                  
'*                    If m.Size = 0 Then
                        Dim TotalesF As String = m.Get("TotalesF")
                        If (TotalesF = Null) Then
                            TotalsF = "0.00"  'NEW NEW
                        End If
                        lblTotaFiado.Text = TotalsF      'NEW NEW                                
                       
'*                    Else
'                        Dim m As Map
'                        m = l.Get(0)
'*                        lblTotaFiado.Text = (m.Get("TotalesF"))
'*                    End If
                Next
This should fix it.
NOTE: As your code stands, if montofiado ever contains more than one entry (parser.NextArray returns a list with more than one entry), only the last entry will be assigned to lblTotalFiado.Text
NOTE 2!!!!!!: One more commented line!!!! Important
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
UPDATE: I've updated the code above (forgot to comment out all of the else portion of the if statement).
 
Upvote 0

Daniel44

Active Member
Licensed User
B4X:
Case TRAERTOTALFIADOS
                'NEW NEW - looks like you don't need to assign montofiado the Json2List result, since you are assigning it parser.NextArray below
                'Dim montofiado As List = Json2List(jobResult)
                Dim montofiado As List

                montofiado = parser.NextArray 'returns a list with maps
                For i = 0 To montofiado.Size - 1
                    Dim m As Map
                    m = montofiado.Get(i)
                    Log (m)
'                 
'*                    If m.Size = 0 Then
                        Dim TotalesF As String = m.Get("TotalesF")
                        If (TotalesF = Null) Then
                            TotalsF = "0.00"  'NEW NEW
                        End If
                        lblTotaFiado.Text = TotalsF      'NEW NEW                               
                      
'*                    Else
'                        Dim m As Map
'                        m = l.Get(0)
'*                        lblTotaFiado.Text = (m.Get("TotalesF"))
'*                    End If
                Next
This should fix it.
NOTE: As your code stands, if montofiado ever contains more than one entry (parser.NextArray returns a list with more than one entry), only the last entry will be assigned to lblTotalFiado.Text
NOTE 2!!!!!!: One more commented line!!!! Important
B4X:
JobDone(Job As HttpJob)
    ProgressDialogHide
    If Job.Success Then
        Dim res As String
        Dim jobResult As String = Job.GetString
        res = Job.GetString2("UTF8")
'        res = res.SubString(1)
        Log("Response from server: " & res)
        Dim parser As JSONParser
        parser.Initialize(res)
        Select Job.JobName
            Case TRAERTOTALFIADOS
                Dim montofiado As List = Json2List(jobResult)
                
                montofiado = parser.NextArray 'returns a list with maps
                For i = 0 To montofiado.Size - 1
                    Dim m As Map
                    m = montofiado.Get(i)
                    Log (m)
                    Dim TotalesF As String = m.Get("TotalesF")
                    If (TotalesF = Null) Then
                        TotalesF = "0.00"  'NEW NEW
                    End If
                    lblTotaFiado.Text = TotalesF
'                    If m.Size = 0 Then
'                        Dim TotalesF As String = m.Get("TotalesF")
'                        If (TotalesF = Null) Then
'                            lblTotaFiado.Text = "0.00"
'                        End If
'                                       
'                       
'                    Else
''                        Dim m As Map
''                        m = l.Get(0)
'                        lblTotaFiado.Text = (m.Get("TotalesF"))
'                    End If
                Next
            Case TRAERTOTALCASH


Still showing null

here's the log


B4X:
--------- beginning of main
** Service (starter) Destroy (ignored)**
** Activity (est) Pause, UserClosed = true **
** Service (httputils2service) Destroy **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesF":null}]
(MyMap) {TotalesF=null}
Response from server: [{"TotalesC":"62112.55"}]
Response from server: []
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Let's do some logging to see what is up
B4X:
            Case TRAERTOTALFIADOS
       montofiado = parser.NextArray 'returns a list with maps
       For i = 0 To montofiado.Size - 1
           Dim m As Map
           m = montofiado.Get(i)
           Log (m)
           Dim TotalesF As String = m.Get("TotalesF")
           Log($"TotalesF's value is ${TotalesF}"$)
           If (TotalesF = Null) Then
               TotalesF = "0.00"  'NEW NEW
               Log($"TotalesF's was null, setting TotalesF to ${TotalesF}"$)
           End If
           lblTotaFiado.Text = TotalesF
           Log($"lblTotaFiado's Text value is ${lblTotaFiado.Text}"$)
       Next
 
Upvote 0

Daniel44

Active Member
Licensed User
Let's do some logging to see what is up
B4X:
            Case TRAERTOTALFIADOS
       montofiado = parser.NextArray 'returns a list with maps
       For i = 0 To montofiado.Size - 1
           Dim m As Map
           m = montofiado.Get(i)
           Log (m)
           Dim TotalesF As String = m.Get("TotalesF")
           Log($"TotalesF's value is ${TotalesF}"$)
           If (TotalesF = Null) Then
               TotalesF = "0.00"  'NEW NEW
               Log($"TotalesF's was null, setting TotalesF to ${TotalesF}"$)
           End If
           lblTotaFiado.Text = TotalesF
           Log($"lblTotaFiado's Text value is ${lblTotaFiado.Text}"$)
       Next

Hey Oliver thank you for being here again.

Here's the Log wiht values to sum

B4X:
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesF":"1000"}]
Response from server: [{"TotalesC":"62112.55"}]
Response from server: [{"idfiado":"1","fechafiado":"2019-11-23 17:13:06","montofiado":"890","detallefiado":"hjhk"},{"idfiado":"2","fechafiado":"2019-11-23 17:13:27","montofiado":"110","detallefiado":"nnnn"}]
(ArrayList) [{idfiado=1, fechafiado=2019-11-23 17:13:06, montofiado=890, detallefiado=hjhk}, {idfiado=2, fechafiado=2019-11-23 17:13:27, montofiado=110, detallefiado=nnnn}]
(ArrayList) [{idfiado=1, fechafiado=2019-11-23 17:13:06, montofiado=890, detallefiado=hjhk}, {idfiado=2, fechafiado=2019-11-23 17:13:27, montofiado=110, detallefiado=nnnn}]
** Service (starter) Destroy (ignored)**
** Activity (est) Pause, UserClosed = true **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesF":"1000"}]
(MyMap) {TotalesF=1000}
TotalesF's value is 1000
lblTotaFiado's Text value is 1000
Response from server: [{"idfiado":"1","fechafiado":"2019-11-23 17:13:06","montofiado":"890","detallefiado":"hjhk"},{"idfiado":"2","fechafiado":"2019-11-23 17:13:27","montofiado":"110","detallefiado":"nnnn"}]
(ArrayList) [{idfiado=1, fechafiado=2019-11-23 17:13:06, montofiado=890, detallefiado=hjhk}, {idfiado=2, fechafiado=2019-11-23 17:13:27, montofiado=110, detallefiado=nnnn}]
(ArrayList) [{idfiado=1, fechafiado=2019-11-23 17:13:06, montofiado=890, detallefiado=hjhk}, {idfiado=2, fechafiado=2019-11-23 17:13:27, montofiado=110, detallefiado=nnnn}]
Response from server: [{"TotalesC":"62112.55"}]

Here's without values to sum more clear

B4X:
Registo conectado a:  
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesF":null}]
(MyMap) {TotalesF=null}
TotalesF's value is null
lblTotaFiado's Text value is null
Response from server: []
Response from server: [{"TotalesC":"62112.55"}]
 
Upvote 0

Daniel44

Active Member
Licensed User
B4X:
Case TRAERTOTALFIADOS
                Dim montofiado As List = Json2List(jobResult)
                
                montofiado = parser.NextArray 'returns a list with maps
                For i = 0 To montofiado.Size - 1
                    Dim m As Map
                    m = montofiado.Get(i)
                    Log (m)
                    Dim TotalesF As String = m.Get("TotalesF")
                    Log($"TotalesF's value is ${TotalesF}"$)
                    If (TotalesF = Null) Then
                        TotalesF = "0.00"  'NEW NEW
                        Log($"TotalesF's was null, setting TotalesF to ${TotalesF}"$)
                    End If
                    lblTotaFiado.Text = TotalesF
                    Log($"lblTotaFiado's Text value is ${lblTotaFiado.Text}"$)
                Next
                
'                montofiado = parser.NextArray 'returns a list with maps
'                For i = 0 To montofiado.Size - 1
'                    Dim m As Map
'                    m = montofiado.Get(i)
''                    Log (m)
''                   
'                    If m.Size = 0 Then
'                        Dim TotalesF As String = m.Get("TotalesF")
'                        If (TotalesF = Null) Then
'                            lblTotaFiado.Text = "0.00"
'                        End If
'                                       
'                       
'                    Else
''                        Dim m As Map
''                        m = l.Get(0)
'                        lblTotaFiado.Text = (m.Get("TotalesF"))
'                    End If
'                Next
            Case TRAERTOTALCASH
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Change the if to
B4X:
If (TotalesF.EqualsIgnoreCase(Null)) Then
 
Upvote 0

Daniel44

Active Member
Licensed User
Change the if to
B4X:
If (TotalesF.EqualsIgnoreCase(Null)) Then

Simply... you're a Genius!

Log

B4X:
Registo conectado a: 
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
--------- beginning of system
Copying updated assets files (14)
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (est) Create, isFirst = true **
** Activity (est) Resume **
Response from server: [{"TotalesF":null}]
(MyMap) {TotalesF=null}
TotalesF's value is null
TotalesF's was null, setting TotalesF to 0.00
lblTotaFiado's Text value is 0.00
Response from server: []
Response from server: [{"TotalesC":"62112.55"}]

B4X:
Case TRAERTOTALFIADOS
                Dim montofiado As List = Json2List(jobResult)
                
                montofiado = parser.NextArray 'returns a list with maps
                For i = 0 To montofiado.Size - 1
                    Dim m As Map
                    m = montofiado.Get(i)
                    Log (m)
                    Dim TotalesF As String = m.Get("TotalesF")
                    Log($"TotalesF's value is ${TotalesF}"$)
                    If (TotalesF.EqualsIgnoreCase(Null)) Then
                        TotalesF = "0.00"  'NEW NEW
                        Log($"TotalesF's was null, setting TotalesF to ${TotalesF}"$)
                    End If
                    lblTotaFiado.Text = TotalesF
                    Log($"lblTotaFiado's Text value is ${lblTotaFiado.Text}"$)
                Next
                
'                montofiado = parser.NextArray 'returns a list with maps
'                For i = 0 To montofiado.Size - 1
'                    Dim m As Map
'                    m = montofiado.Get(i)
''                    Log (m)
''                   
'                    If m.Size = 0 Then
'                        Dim TotalesF As String = m.Get("TotalesF")
'                        If (TotalesF = Null) Then
'                            lblTotaFiado.Text = "0.00"
'                        End If
'                                       
'                       
'                    Else
''                        Dim m As Map
''                        m = l.Get(0)
'                        lblTotaFiado.Text = (m.Get("TotalesF"))
'                    End If
'                Next
            Case TRAERTOTALCASH

Now in my phone the label can show '0,00' Thank you so much Oliver!
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Simply... you're a Genius!
Note quite.
1) Took me too long to get the proper solution (for testing for Null)
2) @mc73 has the correct suggestion that, if at all possible, Null returns from a DB should be avoided (unless you really want to test for it on the client side). Null's are a pain. @Erel does not recommend them (and see the headaches they can cause here: https://www.b4x.com/android/forum/threads/null-not-evaluating-as-null.82458/#content) and see https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi all, glad to see it solved.
If you look back at my post #13 you can see
B4X:
If (TotalesF = "null") Then  LblValues.Text = "0,00 " Else  LblValues.Text = TotalesF
Note the Null worked on as a string "null" which is what the map returned as its value for key TotalesF. Anyway, a good idea to lowercase TotalesF or use EqualIngnoreCase on null.

As Oliver already mentioned there's a possible problem arising from a list having more than one map. I would test for list size (it could be empty, one item, several items) and react accordingly. Another point of possible failure could be a map not containing the expected key (TotalesF).

udg
 
Last edited:
Upvote 0

Daniel44

Active Member
Licensed User
Hi all, glad to see it solved.
If you look back at my post #13 you can see
B4X:
If (TotalesF = "null") Then  LblValues.Text = "0,00 " Else  LblValues.Text = TotalesF
Note the Null worked on as a string "null" which is what the map returned as its value for key TotalesF. Anyway, a good idea to lowercase TotalesF or use EqualIngnoreCase on null.

As Oliver already mentioned there's a possible problem arising from a list having more than one map. I would test for list size (ot could be empty, one item, several items) and react acordingly. Another point of possible failure could be a map not containing the expected key (TotalesF).

udg
Yes thank you all
 
Upvote 0

Daniel44

Active Member
Licensed User
Note quite.
1) Took me too long to get the proper solution (for testing for Null)
2) @mc73 has the correct suggestion that, if at all possible, Null returns from a DB should be avoided (unless you really want to test for it on the client side). Null's are a pain. @Erel does not recommend them (and see the headaches they can cause here: https://www.b4x.com/android/forum/threads/null-not-evaluating-as-null.82458/#content) and see https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/

I thought b4a language hand all that . I've been programing for years in delphi, Vb and php and I know Nulls are a headache but as i said I thought B4A was handling all that issues since here we don't need to cast a variable type B4A does automatically and all these are adventages I thought Nulls were handed automatically as well. I've saw I was wrong. Thank you
 
Upvote 0

nibbo

Active Member
Licensed User
Longtime User
I tend to use a common sub to handle this:

B4X:
Public Sub NumberFromDatabaseField(field As String) As String
    Dim strField As String = field.Trim
    If (strField.Length=0) Or (strField.ToLowerCase="null") Then Return "0"
    If IsNumber(strField) Then
        Return strField
    Else
        Return "0"
    End If
End Sub

Then every time I retrieve data from a remote source just use:

B4X:
NumberFromDatabaseField(m.Get("TotalesF"))

I have similar subs for string and Booleans also; just makes the code more readable if you have to do it a lot.
A lot easier if you have access to the remote code/query and deal with it there of course...
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Public Sub NumberFromDatabaseField(field As String) As String
Dim strField As String = field.Trim
If (strField.Length=0) Or (strField.ToLowerCase="null") Then Return "0"
If IsNumber(strField) Then
Return strField
Else
Return "0"
End If
End Sub
You probably can condense your sub to this:
B4X:
Sub NumberFromDatabaseField(field As String) As String
    Dim strField As String = field.Trim
    If Not (IsNumber(strField)) Then Return "0" 'or "0.00" as desired in this thread
    Return strField
End Sub
 
Upvote 0

Daniel44

Active Member
Licensed User
I tend to use a common sub to handle this:

B4X:
Public Sub NumberFromDatabaseField(field As String) As String
    Dim strField As String = field.Trim
    If (strField.Length=0) Or (strField.ToLowerCase="null") Then Return "0"
    If IsNumber(strField) Then
        Return strField
    Else
        Return "0"
    End If
End Sub

Then every time I retrieve data from a remote source just use:

B4X:
NumberFromDatabaseField(m.Get("TotalesF"))

I have similar subs for string and Booleans also; just makes the code more readable if you have to do it a lot.
A lot easier if you have access to the remote code/query and deal with it there of course...
Hey
I tend to use a common sub to handle this:

B4X:
Public Sub NumberFromDatabaseField(field As String) As String
    Dim strField As String = field.Trim
    If (strField.Length=0) Or (strField.ToLowerCase="null") Then Return "0"
    If IsNumber(strField) Then
        Return strField
    Else
        Return "0"
    End If
End Sub

Then every time I retrieve data from a remote source just use:

B4X:
NumberFromDatabaseField(m.Get("TotalesF"))

I have similar subs for string and Booleans also; just makes the code more readable if you have to do it a lot.
A lot easier if you have access to the remote code/query and deal with it there of course...
Hey nibbo thank you for.answering it looks fine thank you a wil try with this too
 
Upvote 0
Top