Android Question Null not evaluating as Null

Computersmith64

Well-Known Member
Licensed User
Upfront disclaimer: I've been working on my latest project pretty hard for the past few weeks, so I'm getting very tired...

I have a sub that takes a String argument & returns a bitmap. I perform a test on the string to see if it's Null & if it isn't loads the file in the string, else it loads a default image:
B4X:
'In my AppUtils module
Public Sub getMarkerIcon(icon As String) As Bitmap
    Private iconImg As Bitmap
   
    If icon <> Null Then 
        iconImg.Initialize(File.DirAssets, icon) 
    Else 
        iconImg.Initialize(File.DirAssets, "icon_default.png")
    End If
   
    Return CreateScaledBitmap(iconImg, 25dip, 25dip)
End Sub
I call this function from a couple of different places in my Main activity. In one call I use the result from a query & in the other I just pass Null, or a String set to Null.
B4X:
    Private icon As String = Starter.sqlDB.ExecQuerySingleResult2("SELECT GroupIcon FROM tblGroups WHERE GroupName=?", Array As String(group))
    Private m1 As Marker = gmap.AddMarker3(lat, lon, title, AppUtils.getMarkerIcon(icon))

'AND

    Private m1 As Marker = gmap.AddMarker3(lat, lon, title, AppUtils.getMarkerIcon(Null))
'OR
    Private icon as String = Null
    Private m1 As Marker = gmap.AddMarker3(lat, lon, title, AppUtils.getMarkerIcon(icon))
So here's the problem. In the first call (where "icon" is the result of the query) if the query returns Null, it works fine - BUT - if I pass Null, the If statement evaluates to true & the app crashes.

According to the documentation, the return type from ExecQueryResult2 is either a String, or Null. The variable ("icon") receiving the return value from the query is a String. Even if I declare a String, assign Null to it & then pass it to the sub, it still crashes. If I change the sub argument type to Object, it works fine.

Why does it work when a String that has been set to Null by ExecQuerySingleResult2 is passed, but not when a String that has been set to Null (or just Null) is passed?

- Colin.
 

Star-Dust

Expert
Licensed User
I solved every problem as I did:

B4X:
Public Sub getMarkerIcon(icon As String) As Bitmap
    Private iconImg As Bitmap
  
    Try
        iconImg.Initialize(File.DirAssets, icon)
    Catch
        iconImg.Initialize(File.DirAssets, "icon_default.png")
    End Try
  
    Return CreateScaledBitmap(iconImg, 25dip, 25dip)
End Sub
So no matter what returns, null or empty ... goes wrong and passes to the standard image
 

Computersmith64

Well-Known Member
Licensed User
I solved every problem as I did:

B4X:
Public Sub getMarkerIcon(icon As String) As Bitmap
    Private iconImg As Bitmap

    Try
        iconImg.Initialize(File.DirAssets, icon)
    Catch
        iconImg.Initialize(File.DirAssets, "icon_default.png")
    End Try

    Return CreateScaledBitmap(iconImg, 25dip, 25dip)
End Sub
So no matter what returns, null or empty ... goes wrong and passes to the standard image
Yep - that will work, as does changing "icon As String" to "icon As Object" - but I'm still keen to know why it doesn't work when icon is declared as a String...

I know that Erel will probably have a perfectly logical explanation as to why. I'd like to know what it is!

- Colin.
 

Star-Dust

Expert
Licensed User
I like this
B4X:
Public Sub getMarkerIcon(iconfile As String) As Bitmap
   Try
      Return CreateScaledBitmap(LoadBitmap(File.DirAssets, iconfile), 25dip, 25dip)
   Catch
      Return CreateScaledBitmap(LoadBitmap(File.DirAssets, "icon_default.png"), 25dip, 25dip)
   End Try
End Sub
 
Last edited:

Star-Dust

Expert
Licensed User
Add Log(IconFile)
so can see what return

Yep - that will work, as does changing "icon As String" to "icon As Object" - but I'm still keen to know why it doesn't work when icon is declared as a String...

I know that Erel will probably have a perfectly logical explanation as to why. I'd like to know what it is!

- Colin.
 

Computersmith64

Well-Known Member
Licensed User
Add Log(IconFile)
so can see what return
It's not the return value that's the problem - it's the value of "icon". When it's declared as a String & I pass Null to it, the statement:

B4X:
    If icon <> Null
evaluates to True - even though when I put a Log(icon) statement before it the log shows Null.

- Colin.
 

Star-Dust

Expert
Licensed User
Icon=Null or icon="Null", becouse is different
 

Computersmith64

Well-Known Member
Licensed User
I lime this
B4X:
Public Sub getMarkerIcon(iconfile As String) As Bitmap
   Try
      Return CreateScaledBitmap(LoadBitmap(File.DirAssets, iconfile), 25dip, 25dip)
   Catch
      Return CreateScaledBitmap(LoadBitmap(File.DirAssets, "icon_default.png"), 25dip, 25dip)
   End Try
End Sub
Also - my preference is not to write code that will intentionally trigger an exception. There are times when it is acceptable to pass Null to this sub so I don't want to trigger an exception every time I do. :)

- Colin.
 

Star-Dust

Expert
Licensed User
Try also
If isNull(icon) Then
 

Computersmith64

Well-Known Member
Licensed User
Icon=Null or icon="Null", becouse is different
Yes - I'm aware of that. The result of the query generates either a String or Null (not "Null") & I am passing Null (not "Null").

- Colin.
 

Star-Dust

Expert
Licensed User
Now Exist :p:p:p:p

B4X:
Sub IsNull(O as Object) ad Boolean
     Return (O=Null)
End Sub
 

Star-Dust

Expert
Licensed User
Also - my preference is not to write code that will intentionally trigger an exception. There are times when it is acceptable to pass Null to this sub so I don't want to trigger an exception every time I do. :)

- Colin.
This is your preference, but sometimes managing exceptions appears to be the most practical solution is more reasonable. That does not make you waste precious time
 

Computersmith64

Well-Known Member
Licensed User
Now Exist :p:p:p:p

B4X:
Sub IsNull(O as Object) ad Boolean
     Return (O=Null)
End Sub
Yeah - but I can achieve the same thing by just declaring:
B4X:
    Public Sub getMarkerIcon(icon as Object) as Bitmap
So I already have a workaround, but I want to know why Null evaluates differently between 2 different strings. What is is that makes ExecQuerySingleResult return a "true" Null, but passing Null doesn't work?

- Colin.
 

Computersmith64

Well-Known Member
Licensed User
This is your preference, but sometimes managing exceptions appears to be the most practical solution is more reasonable. That does not make you waste precious time
I use Try Catch End Try blocks in my code all the time to catch unintended exceptions - but I don't like intentionally triggering them. I'd rather write code that only triggers exceptions when something unanticipated happens.

- Colin.
 

Computersmith64

Well-Known Member
Licensed User

Star-Dust

Expert
Licensed User
Yes - I'm aware of that. The result of the query generates either a String or Null (not "Null") & I am passing Null (not "Null").

- Colin.
I had posed with the question specifically because often I also found that the string assumes the "Null" value ;)
 

Star-Dust

Expert
Licensed User
Thanks - that does explain why assigning Null to a string doesn't work (because it gets converted to "Null"), but it doesn't explain how ExecQuerySingleResult is able to assign Null to a string variable without it being converted to a string.

- Colin.
Probably the value that returns ExecQuerySingleResult is not a string but an object, because it could also return a numeric value, or any other type contained in the database
 

Computersmith64

Well-Known Member
Licensed User
Probably the value that returns ExecQuerySingleResult is not a string but an object, because it could also return a numeric value, or any other type contained in the database
That could be true, in which case the documentation is incorrect because it states that the return type is String.

- Colin.
 
Top