Android Question [SOLUTION] null receiver error

giggetto71

Active Member
Licensed User
Longtime User
Hi I have a question. Say I have a custom type and I make a map of object based on that custom type. then I use kvs to put that map to save it. when the app starts the map is restored by getting from the kvs collection. So far so good. no problem here.
now say I change the custom type and I need to add a list element to it. when I do the get from kvs of course the elements in kvs do not contain the new list elem to that is null of course so if try to inizialize the list I get " null receiver". is there a way to do that?
simplified example (not the real code)

B4X:
'version 1'
type test1(i as int, s as string)
private MyMap as map
'....

private testobj as test1
testobj.i = 1
testobj.s = s
''.....
MyMap.put(testobj,mykey)
....
kvs.put("MyMapKVS")


............
'when the app opens:'
MyMap = kvs.get("MyMapKVS")
'....get one element
private MyObj as test1
MyObj.initialize
MyObj = MyMap.get(Keyx)
....

' now in version 2 of the app I add the list'
type test1(i as int, s as string,l as list)
private MyMap as map
'....
'when the app opens:'
MyMap = kvs.get("MyMapKVS")  'MyMapKVS was saved in version 1 so the objects in do not have the list element
'....get one element
private MyObj as test1
MyObj.initialize
MyObj = MyMap.get(Keyx)
'here if I do '
MyObj.l.initialize 'here I get the null receiver error
 

DonManfred

Expert
Licensed User
Longtime User
Upload a small project showing the problem
 
Upvote 0

giggetto71

Active Member
Licensed User
Longtime User
here it is. pls run this as version 1 which works fine. you will be able to add objects to mymap and store and retrieve from kvs.
now imagine you need to make a version 2 of the app and add l as list in the TestYpe def (you can uncomment in the code).
and then in the activity create you know that the object got from kvs will NOT have the list initialized so you try to initialize for example the first element of the map. that's were you get the Null receiver error.
thank you very much for your help as usual...
 

Attachments

  • NullReceiver.zip
    9.9 KB · Views: 46
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Change this: MyObj.l.initialize to:
B4X:
Dim l As List
l.Initialize
MyObj.l = l

Do note that modifying serialized custom types can be tricky. You can't for example rename a field.
In some cases it is easier to create a new custom type that holds the older one (or copy the fields to the new one).
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Button1_Click in V2.
You, the Developer know what you did add..

B4X:
Sub Button1_Click
    If MyMap.Size = 0 Then
        Log("empty map")
        Return
    End If
    For Each key As String In MyMap.Keys
        Private TempObj As TestType
        TempObj = MyMap.Get(key)
        If TempObj.l = Null Then
            'If TempObj.l.IsInitialized = False Then
            Log("List not Initialized")
            Dim l As List
            l.Initialize
            TempObj.l = l
        End If
        Log($"${TempObj.i} - ${TempObj.s} - ${TempObj.l}"$)
        
    Next
    'For ii = 0 To MyMap.Size-1
    '   Private TempObj As TestType
    '   TempObj = MyMap.GetValueAt(ii)
    '   Log(TempObj.i & "---" & TempObj.s)   
    'Next
End Sub
 
Upvote 0

giggetto71

Active Member
Licensed User
Longtime User
thank you very much @Erel and @DonManfred .
@Erel . I understand it can be tricky but maintaining a published app sometimes if you need to add some functionality it's required...I did it other times in the past but only using basic types (by the way I got similar problems in the past for add strings element to the custom type but in the case I could test if the added element was null and I could set it to empty string....
again thank you very very much for your super prompt support as usual.
 
Upvote 0
Top