Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-11399] iOS: Ti.App.Properties.setObject cannot save object with null values in it

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2013-06-21T10:29:20.000+0000
Affected Version/sn/a
Fix Version/sRelease 3.1.0, 2012 Sprint 25, 2012 Sprint 25 API
ComponentsiOS
Labelsinsight, module_app_properties, parity, qe-testadded
ReporterGijs Nieuwenhuis
AssigneeVishal Duggal
Created2012-09-14T04:13:12.000+0000
Updated2013-06-21T10:29:20.000+0000

Description

Problem

When trying to set an object in the client side properties by using "Ti.App.Properties.setObject()", the object that contains a key that has a null value it won't be saved.

Actual result

When replacing the 'something' -key with a non-null value, the property however CAN be saved.

Repro sequence

var win = Ti.UI.createWindow({ backgroundColor: 'white' });
   
var objectWithNullValue = {
  expires_at: 1347623585,
  value: {
    something: null
  }
};

var objectWithoutNullValue = {
  expires_at: 1347623585,
  value: {
    something: 'value'
  }
};
  
Ti.App.Properties.setObject('Object1', objectWithNullValue);
Ti.App.Properties.setObject('Object2', objectWithoutNullValue); 
 
 
Ti.API.info('----- object 1 -----');
Ti.API.info(Ti.App.Properties.getObject('Object1'));
Ti.API.info('Type of Object1: ' + typeof Ti.App.Properties.getObject('Object1'));
Ti.API.info('Value of Object1: ' + Ti.App.Properties.getObject('Object1'));
Ti.API.info('Stringified value of Object1: ' + JSON.stringify(Ti.App.Properties.getObject('Object1')));
 
Ti.API.info('----- object 2 -----');
Ti.API.info(Ti.App.Properties.getObject('Object2'));
Ti.API.info('Type of Object2: ' + typeof Ti.App.Properties.getObject('Object2'));
Ti.API.info('Value of Object2: ' + Ti.App.Properties.getObject('Object2'));
Ti.API.info('Stringified value of Object2: ' + JSON.stringify(Ti.App.Properties.getObject('Object2')));
 
win.open();

Ti.API.info('----- My name -----');
Ti.App.Properties.setObject( "object" , { name: "eduardo" , lastName: null } );
Ti.API.info(Ti.App.Properties.getObject('object'));

iOS Console output

[INFO] Detected third-party module: ti.location/1.0
[INFO] Titanium SDK version: 3.0.0 (10/08/12 21:09 7bf73ff)
[INFO] iPhone Device family: universal
[INFO] iPhone SDK version: 5.1
[INFO] iPhone simulated device: iphone
[WARN] The project seems to be having custom info.plist which does not contain  the CFBundleShortVersionString key
[INFO] Generating the missing CFBundleShortVersionString key
[INFO] Minimum iOS version: 4.0 Linked iOS Version 5.1
[INFO] Launching application in Simulator
[INFO] Launched application in Simulator (5.11 seconds)
[INFO] Application started
[INFO] 1BestPractices/1.0 (3.0.0.v20121008210903.7bf73ff)
[INFO] ----- object 1 -----
[INFO] {
    value =     {
    };
}
[INFO] Type of Object1: object
[INFO] Value of Object1: [object Object]
[INFO] Stringified value of Object1: {"value":{}}
[INFO] ----- object 2 -----
[INFO] {
    "expires_at" = 1347623585;
    value =     {
        something = value;
    };
}
[INFO] Type of Object2: object
[INFO] Value of Object2: [object Object]
[INFO] Stringified value of Object2: {"expires_at":1347623585,"value":{"something":"value"}}
[INFO] ----- My name -----
2012-10-11 17:12:48.872 1BestPractices[6080:1a903] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
    lastName = "<null>";
    name = eduardo;
}' of class '__NSCFDictionary'.  Note that dictionaries and arrays in property lists must also contain only property values.
[INFO] <null>

Android Console logs

10-11 17:12:29.501: I/TiApplication(3486): (main) [0,0] checkpoint, app created.
10-11 17:12:29.540: I/TiApplication(3486): (main) [37,37] Titanium 3.0.0 (2012/10/08 21:09 7bf73ff)
10-11 17:12:29.704: I/TiDbHelper(3486): (main) [171,208] No value in database for platform key: 'unique_machine_id' returning supplied default ''
10-11 17:12:29.712: I/TiDbHelper(3486): (main) [4,212] No value in database for platform key: 'hardware_machine_id' returning supplied default ''
10-11 17:12:29.766: I/TiApplication(3486): (main) [58,270] Titanium Javascript runtime: v8
10-11 17:12:29.774: D/dalvikvm(3486): Trying to load lib /data/data/com.appc.test/lib/libstlport_shared.so 0x4051ccb8
10-11 17:12:29.774: D/dalvikvm(3486): Added shared lib /data/data/com.appc.test/lib/libstlport_shared.so 0x4051ccb8
10-11 17:12:29.774: D/dalvikvm(3486): No JNI_OnLoad found in /data/data/com.appc.test/lib/libstlport_shared.so 0x4051ccb8, skipping init
10-11 17:12:29.774: D/dalvikvm(3486): Trying to load lib /data/data/com.appc.test/lib/libkroll-v8.so 0x4051ccb8
10-11 17:12:29.790: D/dalvikvm(3486): Added shared lib /data/data/com.appc.test/lib/libkroll-v8.so 0x4051ccb8
10-11 17:12:29.821: I/TiRootActivity(3486): (main) [0,0] checkpoint, on root activity create, savedInstanceState: null
10-11 17:12:29.852: I/TiAnalyticsDb(3486): (main) [35,35] Upgrading Database from 1 to 4
10-11 17:12:30.016: E/TiApplication(3486): (KrollRuntimeThread) [159,194] APP PROXY: ti.modules.titanium.app.AppModule@405e3f90
10-11 17:12:30.094: I/TiAPI(3486):  ----- object 1 -----
10-11 17:12:30.094: I/TiAPI(3486):  [object Object]
10-11 17:12:30.094: I/TiAPI(3486):  Type of Object1: object
10-11 17:12:30.094: I/TiAPI(3486):  Value of Object1: [object Object]
10-11 17:12:30.094: I/TiAPI(3486):  Stringified value of Object1: {"expires_at":1347623585,"value":{"something":null}}
10-11 17:12:30.094: I/TiAPI(3486):  ----- object 2 -----
10-11 17:12:30.094: I/TiAPI(3486):  [object Object]
10-11 17:12:30.094: I/TiAPI(3486):  Type of Object2: object
10-11 17:12:30.094: I/TiAPI(3486):  Value of Object2: [object Object]
10-11 17:12:30.094: I/TiAPI(3486):  Stringified value of Object2: {"expires_at":1347623585,"value":{"something":"value"}}
10-11 17:12:30.110: D/LSAPP_TelMon(783): onCellTowerChanged CDMA :: {"NetTyp":"CDMA","BaseStnLat":"2147483647","NetOp":"33404","BaseStnId":"623","BaseStnLng":"2147483647","CntryISO":"mx","NetId":"0","SysId":"24587"}
10-11 17:12:30.126: D/LSAPP_TelMon(783): Telmon : celltower changed...new cell...clear bouncing cells upon new cell and no pending timer 
10-11 17:12:30.126: D/LSAPP_TelMon(783): emptyBouncingCells :: 
10-11 17:12:30.173: I/TiAPI(3486):  ----- My name -----
10-11 17:12:30.180: I/TiAPI(3486):  [object Object]

Associated Community thread

http://developer.appcelerator.com/question/139212/sdk-210-propertiessetobject-error-when-setting-null

Comments

  1. Gijs Nieuwenhuis 2012-09-14

    Can't seem to save it with Ti.App.Properties.setList() either when the object has null values..
  2. Eduardo Gomez 2012-09-19

    @Gijs Nieuwenhuis What is your iOS version? Can you paste an actual sample to test this including your console output? "Ti.App.Properties.setObject()" can save null values as per sample below:

    repro sequence

       var win = Ti.UI.createWindow({ backgroundColor: 'white' });
        
       Ti.App.Properties.setBool('boolValue1', true);
       Ti.API.info('The value of the boolValue1 property is: ' + Ti.App.Properties.getBool('boolValue1'));
        
       Ti.App.Properties.setBool('boolValue2', false);
       Ti.API.info('The value of the boolValue2 property is: ' + Ti.App.Properties.getBool('boolValue2'));
        
       Ti.App.Properties.setBool('boolValue3', null);
       Ti.API.info('The value of the boolValue3 property is: ' + Ti.App.Properties.getBool('boolValue3'));
        
       Ti.App.Properties.setBool('boolValue4', undefined);
       Ti.API.info('The value of the boolValue4 property is: ' + Ti.App.Properties.getBool('boolValue4'));
       
       var savedObject = {
           expires_at: 1347623585,
           value: {
               something: null
          }
       };
       
       Ti.App.Properties.setObject(savedObject, null);
       Ti.API.info('The value of the Object1 property is: ' + Ti.App.Properties.getObject(savedObject));
        
       Ti.App.Properties.setObject('Object2', undefined);
       Ti.API.info('The value of the Object2 property is: ' + Ti.App.Properties.getObject('Object2'));
        
       win.open();
       

    Console output

       [INFO] One moment, building ...
       [INFO] Detected third-party module: ti.location/1.0
       [INFO] Detected third-party module: ti.location/1.0
       [INFO] Titanium SDK version: 2.1.2 (08/24/12 14:46 ed7f777)
       [INFO] iPhone Device family: universal
       [INFO] iPhone SDK version: 5.1
       [INFO] iPhone simulated device: iphone
       [WARN] The project seems to be having custom info.plist which does not contain  the CFBundleShortVersionString key
       [INFO] Generating the missing CFBundleShortVersionString key
       [INFO] Minimum iOS version: 4.0
       [INFO] Launching application in Simulator
       [INFO] Launched application in Simulator (4.40 seconds)
       [INFO] Application started
       [INFO] 1BestPractices/1.0 (2.1.2.GA.ed7f777)
       [INFO] The value of the boolValue1 property is: true
       [INFO] The value of the boolValue2 property is: false
       [INFO] The value of the boolValue3 property is: null
       [INFO] The value of the boolValue4 property is: null
       [INFO] The value of the Object1 property is: null
       [INFO] The value of the Object2 property is: null
       
  3. Eduardo Gomez 2012-09-26

    It's been a week now, closing due to age in no response.
  4. Gijs Nieuwenhuis 2012-10-10

    Hi Eduardo, i've been away for a while so I couldn't respond within the required timespan. Anyway, I tested your code and below my console output.
       [INFO] One moment, building ...
       [INFO] Titanium SDK version: 2.1.0 (06/28/12 12:16 6e3cab6)
       [INFO] iPhone Device family: universal
       [INFO] iPhone SDK version: 6.0
       [INFO] iPhone simulated device: iphone
       [INFO] Launching application in Simulator
       dyld: DYLD_ environment variables being ignored because main executable (/usr/bin/osascript) is code signed with entitlements
       [INFO] Launched application in Simulator (14.57 seconds)
       [INFO] Application started
       [INFO] TestProject/1.0 (2.1.0.GA.6e3cab6)
       [INFO] The value of the boolValue1 property is: true
       [INFO] The value of the boolValue2 property is: false
       [INFO] The value of the boolValue3 property is: null
       [INFO] The value of the boolValue4 property is: null
       [INFO] The value of the Object1 property is: null
       [INFO] The value of the Object2 property is: null
       
    However, I don't really get what you're trying to test with these lines as you are not using the setObject method like it is meant to be used (see http://docs.appcelerator.com/titanium/2.1/index.html#!/api/Titanium.App.Properties-method-setObject) when trying to save the savedObject property in the client side properties. I rewrote the code a bit to show you my problem:
       var win = Ti.UI.createWindow({ backgroundColor: 'white' });
         
       var objectWithNullValue = {
         expires_at: 1347623585,
         value: {
           something: null
         }
       };
       
       var objectWithoutNullValue = {
         expires_at: 1347623585,
         value: {
           something: 'value'
         }
       };
        
       Ti.App.Properties.setObject('Object1', objectWithNullValue);
       Ti.App.Properties.setObject('Object2', objectWithoutNullValue);
       
       Ti.API.info('----- object 1 -----');
       Ti.API.info(Ti.App.Properties.getObject('Object1'));
       Ti.API.info('Type of Object1: ' + typeof Ti.App.Properties.getObject('Object1'));
       Ti.API.info('Value of Object1: ' + Ti.App.Properties.getObject('Object1'));
       Ti.API.info('Stringified value of Object1: ' + JSON.stringify(Ti.App.Properties.getObject('Object1')));
       
       Ti.API.info('----- object 2 -----');
       Ti.API.info(Ti.App.Properties.getObject('Object2'));
       Ti.API.info('Type of Object2: ' + typeof Ti.App.Properties.getObject('Object2'));
       Ti.API.info('Value of Object2: ' + Ti.App.Properties.getObject('Object2'));
       Ti.API.info('Stringified value of Object2: ' + JSON.stringify(Ti.App.Properties.getObject('Object2')));
       
       win.open();
       
    Console output when I execute these lines:
       [INFO] One moment, building ...
       [INFO] Titanium SDK version: 2.1.3 (10/02/12 16:16 15997d0)
       [INFO] iPhone Device family: universal
       [INFO] iPhone SDK version: 6.0
       [INFO] iPhone simulated device: iphone
       [INFO] Performing full rebuild. This will take a little bit. Hold tight...
       [INFO] Minimum iOS version: 4.3 Linked iOS Version 6.0
       [INFO] Performing clean build
       [INFO] Launching application in Simulator
       [INFO] Launched application in Simulator (34.45 seconds)
       [INFO] Application started
       [INFO] TestProject/1.0 (2.1.3.GA.15997d0)
       [INFO] ----- object 1 -----
       [INFO] <null>
       [INFO] Type of Object1: object
       [INFO] Value of Object1: null
       [INFO] Stringified value of Object1: null
       [INFO] ----- object 2 -----
       [INFO] {
           "expires_at" = 1347623585;
           value =     {
               something = value;
           };
       }
       [INFO] Type of Object2: object
       [INFO] Value of Object2: [object Object]
       [INFO] Stringified value of Object2: {"expires_at":1347623585,"value":{"something":"value"}}
       
    Mijn environment info: * iPhone SDK version: 6.0 * Titanium SDK: 2.1.3 GA As you can see the application doesn't crash, however objects are still not saved when they have null values in them. Please reopen this issue.
  5. Eduardo Gomez 2012-10-11

    Added labels, test case updated & logs appended. Moving to main project to dig into it.
  6. Vishal Duggal 2012-12-04

    Pull pending https://github.com/appcelerator/titanium_mobile/pull/3523
  7. Paras Mishra 2013-01-22

    Ti.App.Properties.setObject can save object with null values in it. Verified on : SDK version: 3.1.0.v20130111163212 CLI version : 3.0.23 OS : MAC OSX 10.7.5 XCode : 4.5.1
  8. Priya Agarwal 2013-06-21

    Reopening just to update label
  9. Priya Agarwal 2013-06-21

    Updated label and verified. Tested on: Device: Nexus 7 tab Android Version 4.1 and Simulator 6.0 SDK:3.1.2.v20130619101604 Appcelerator Studio: 3.1.1.201306131423 OS: OSX 10.8 acs:1.0.3 alloy:1.1.3 npm:1.2.14 titanium:3.1.1 titanium-code-processor:1.0.1

JSON Source