{ "id": "136717", "key": "TIMOB-17751", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "2", "description": "The problem described is an issue which will never be fixed.", "name": "Won't Fix" }, "resolutiondate": "2014-12-04T16:54:09.000+0000", "created": "2014-09-17T09:19:50.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "TCSupport", "alloy", "bug", "ios", "ipad", "object", "property" ], "versions": [ { "id": "15422", "description": "Release 3.3.0", "name": "Release 3.3.0", "archived": false, "released": true, "releaseDate": "2014-07-16" }, { "id": "15972", "description": "Release 3.4.0", "name": "Release 3.4.0", "archived": false, "released": true, "releaseDate": "2014-09-28" } ], "issuelinks": [], "assignee": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-30T20:56:42.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "h4. Problem Description\r\nIf I have an object (status:{}) inside an object (Ti.UI.View), and I want to edit/add a new property to 'status', in android works perfectly, but on iOS it doesn't change the property, defined on 'Ti.UI.View' creation.\r\n\r\nh4. Steps to reproduce\r\n1. Create a new mobile project (Classic Titanium)\r\n2. Paste this sample into app.js:\r\n{code}\r\nvar win = Titanium.UI.createWindow({ \r\n backgroundColor:'#000',\r\n layout:'vertical'\r\n});\r\n \r\nvar APPNAME = {\r\n \"UI\":{\r\n \"Buttons\":function(props) {\r\n \r\n var button = Ti.UI.createView({\r\n top:100,\r\n height:200,\r\n status:{\r\n selected:false,\r\n inactive:false\r\n },\r\n backgroundColor:\"white\",\r\n select:function(sttz) {\r\n \r\n if(sttz) {\r\n \r\n this.status[\"selected\"] = true;\r\n \r\n this.backgroundColor = \"red\";\r\n }\r\n else {\r\n \r\n this.status[\"selected\"] = false;\r\n \r\n this.backgroundColor = \"white\";\r\n }\r\n \r\n console.log(\"selected status: \"+this.status.selected);\r\n \r\n }\r\n });\r\n \r\n button.addEventListener(\"click\",function() {\r\n \r\n if(!this.status.selected) {\r\n this.select(true);\r\n }\r\n else {\r\n this.select(false);\r\n }\r\n \r\n });\r\n \r\n return button;\r\n }\r\n }\r\n};\r\n \r\nvar exemple_btn = APPNAME.UI.Buttons();\r\nwin.add(exemple_btn);\r\nwin.open();\r\n{code}\r\n3. Run it in device. \r\n4. Click on the White box. It should turn red. Click in the red box. It should turn white. Repeat. \r\n\r\nh4. Expected Results\r\nWhen you click in the box, it should go from white to red and viceversa. \r\n\r\nh4. Actual Results\r\nIt's working fine in Android, failing in iOS. ", "attachment": [ { "id": "51331", "filename": "exemple_ipad.zip", "author": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "created": "2014-09-17T09:19:50.000+0000", "size": 3850464, "mimeType": "application/zip" } ], "flagged": false, "summary": "iOS8: unable to set object property inside object", "creator": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "subtasks": [], "reporter": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "environment": "Mac OS X 10.9.4, \r\nTitanium Studio: 3.3.0.201407100905, \r\nAlloy 1.4.0, \r\niOS iPad simulator 7.1, \r\n\r\nAlso tested with:\r\nMobile SDK 3.4.0-RC\r\niOS8\r\niphone6\r\n", "comment": { "comments": [ { "id": "325425", "author": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "body": "I noticed that there has been activity around this error, as no one commented yet, is there any alternative that I should try?", "updateAuthor": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "created": "2014-09-24T15:17:47.000+0000", "updated": "2014-09-24T15:17:47.000+0000" }, { "id": "334337", "author": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "body": "Hi, I'm just writing this comment to know if there is someone working on this issue, I've 2 complex apps that it's supposed to run on iPad, and I'm kinda stuck", "updateAuthor": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "created": "2014-12-02T15:38:25.000+0000", "updated": "2014-12-02T15:38:25.000+0000" }, { "id": "334553", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Our general recommendation has always been to not modify the proxy objects (the objects you get back from a Ti.UI.create* method). See the [best practices guide|http://docs.appcelerator.com/titanium/latest/#!/guide/Coding_Best_Practices-section-30082362_CodingBestPractices-Don%27tExtendTitaniumPrototypes] or perhaps the [article I wrote for TiDev.io|http://www.tidev.io/2014/03/27/memory-management/] for background information. In essence, Titanium proxies are not true JavaScript objects and should be treated as immutable (in terms of adding or attempting to override properties and methods). Under the covers, our Android and iOS implementations are different enough, that this works to some extent on Android while it is more likely to cause problems on iOS. \r\n\r\nFrom what I see of your app's needs, it seems you could use a separate (true JavaScript) object to maintain state information for your UI components. Then, applyProperties() as needed to update their UI state.", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-12-03T17:35:36.000+0000", "updated": "2014-12-03T17:35:36.000+0000" }, { "id": "334846", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Try this\r\n{code} \r\nselect:function(sttz) {\r\n var status = this.status;\r\n if(sttz) {\r\n status.selected = true\r\n this.backgroundColor = \"red\";\r\n }\r\n else {\r\n status.selected = false;\r\n this.backgroundColor = \"white\";\r\n }\r\n //IOS proxies are not true JS Objects and any undefined properties need to be \r\n //explicitly reset after modification\r\n this.status = status;\r\n console.log(\"selected status: \"+this.status.selected);\r\n}\r\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-12-04T16:20:44.000+0000", "updated": "2014-12-04T16:20:44.000+0000" }, { "id": "334856", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Workaround in comments", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-12-04T16:54:09.000+0000", "updated": "2014-12-04T16:54:09.000+0000" }, { "id": "334874", "author": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "body": "That works, but I have some objects that have many levels of objects and it will be difficult to applicate that to everything.\r\n\r\nSo instead of pass the properties inside a function and attribute them that way, a create a true javascript object, and work on it.\r\n\r\nexemple:\r\n{code:java|borderStyle=solid}\r\nvar btn = (props) {\r\n\r\n var obj {\r\n \"status\":{\r\n \"selected\":true,\r\n \"inactive\":false\r\n },\r\n \"element\":Ti.UI.createView({\r\n })\r\n };\r\n\r\n obj.select = function(status) {\r\n ...\r\n };\r\n\r\n return obj.element;\r\n};\r\n\r\nvar test = new btn({\r\n \"title\":\"test\"\r\n});\r\n\r\ntest.select(true);\r\n\r\n{code}", "updateAuthor": { "name": "ricardo_jcp", "key": "ricardo_jcp", "displayName": "Ricardo Pereira", "active": true, "timeZone": "Europe/Lisbon" }, "created": "2014-12-04T18:46:46.000+0000", "updated": "2014-12-04T18:50:50.000+0000" }, { "id": "416379", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as \"Won't Fix\". There has been no update for a while. If there is any problem, please open a new ticket.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-30T20:56:42.000+0000", "updated": "2017-03-30T20:56:42.000+0000" } ], "maxResults": 10, "total": 10, "startAt": 0 } } }