Titanium JIRA Archive
Alloy (ALOY)

[ALOY-1477] Regression: Missing model attributes cause error on collection data binding

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2016-03-29T17:37:52.000+0000
Affected Version/salloy 1.8.0, alloy 1.8.3
Fix Version/sRelease 5.2.2, alloy 1.8.4
ComponentsModels
Labelsn/a
ReporterFokke Zandbergen
AssigneeFokke Zandbergen
Created2016-03-29T10:06:01.000+0000
Updated2016-03-31T23:24:36.000+0000

Description

ALOY-1369 solved one data-binding issue, but uncovered another. _.template() demands all variables used in a template to exist. Now ALOY-1369 uses this method apps will error if this is not the case. A very typical use case is when you add a new model to a collection and use an auto incremented primary key. In this case that field will be empty when Alloy first updates the UI in response to create. Once the model has been synced to the DB Alloy would update the UI again to show the now populated field. But since Alloy 1.8.0 it would never get there because of the error. The solution is likely to be found in how we use _.template() for model data-binding. Here don't pass the individual model fields as variables but the object as a whole. _.template() seems to have no problem with properties of that object being empty and simply renders an empty string. *index.xml*
<Alloy>
	<Model src="mymodel" />
	<Collection src="mymodel" />
	<Window>
		<ScrollView layout="vertical">
			<Label top="30" text="{mymodel.id} - {mymodel.title}" />
			<ListView>
				<ListSection dataCollection="mymodel">
					<ListItem title="{id} - {title}" />
				</ListSection>
			</ListView>
			<Button onClick="createModel">Create Model</Button>
		</ScrollView>
	</Window>
</Alloy>
*index.js*
Alloy.Models.mymodel.set({
  id: 0,
  title: 'mod TITLE'
});

Alloy.Collections.mymodel.reset([{
  id: 0,
  title: 'col TITLE'
}]);

$.index.open();

function createModel() {
  Alloy.Collections.mymodel.create({
    title: 'crt TITLE'
  });
}
*mymodel.js*
exports.definition = {
  config: {
    "columns": {
      "id": "INTEGER PRIMARY KEY AUTOINCREMENT",
      "title": "TEXT"
    },
    "adapter": {
      "type": "sql",
      "collection_name": "mymodel",
      "idAttribute": "id"
    }
  }
};
*Template code*
[INFO]  var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
[INFO]  with(obj||{}){
[INFO]  __p+='{mymodel.id} - {mymodel.title}';
[INFO]  }
[INFO]  return __p;
[INFO]
[INFO]  var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
[INFO]  with(obj||{}){
[INFO]  __p+=''+
[INFO]  ((__t=(id))==null?'':__t)+
[INFO]  ' - '+
[INFO]  ((__t=(title))==null?'':__t)+
[INFO]  '';
[INFO]  }
[INFO]  return __p;
*Error*
[ERROR] Script Error {
[ERROR]     column = 10;
[ERROR]     line = 4;
[ERROR]     message = "Can't find variable: id";
Found by SO user: http://stackoverflow.com/questions/36274177/alloy-data-binding-error-after-alloy-1-8-upgrade

Comments

  1. Fokke Zandbergen 2016-03-29

    PR: https://github.com/appcelerator/alloy/pull/778 To test: 1. Run jake app:run dir=testing/ALOY-1234 with Alloy 1.8.3 and confirm the spec fails 2. Run again with fix and confirm the spec passes
  2. Feon Sua Xin Miao 2016-03-29

    PR merged. Alloy@1.8.4
  3. Anna 2016-03-30

    with Alloy 1.8.4 the problem still happen....
  4. Fokke Zandbergen 2016-03-30

    [~amurcia] could you give me a reproducible test case? The test case included in the description and PR test app does work with 1.8.4
  5. Anna 2016-03-30

    Yes, this is my example: Model definition: http://pastebin.com/AhnPBQ2q Code: http://pastebin.com/du95qk2r
  6. Fokke Zandbergen 2016-03-30

    [~amurcia] Let's chat on TiSlack (fokkezb) or Skype (fokke.zandbergen). I took some changes to get those snippets work at all and after it did it worked on both Alloy 1.7.35 and 1.8.4 for me: http://get.fokkezb.nl/_/5mhW77c
  7. Anna 2016-03-30

    It works now doing this at console: appc use 5.2.1-12 from here: http://www.appcelerator.com/blog/2016/03/release-candidates-for-titanium-appcelerator-cli-5-2-1/#comment-157507
  8. Fokke Zandbergen 2016-03-30

    [~amurcia] if you are using the appc CLI then that will use the Alloy CLI bundled with what you select via appc use. You can see the Alloy version via appc alloy -v. Could you let me know what Alloy version it was that was failing? BTW, appc use 5.2.1 will get you the GA version of 5.2.1-12
  9. Anna 2016-03-30

    appc 5.0.6 with alloy 1.8.4 -> FAIL appc 5.2.1-12 with alloy 1.8.4 -> OK
  10. Fokke Zandbergen 2016-03-30

    [~amurcia] I'm sorry but here's no appc use 5.0.6 and appc use 5.2.1-12 comes with Alloy 1.7.35 (appc alloy -v). Could you double check?
  11. Anna 2016-03-30

    This is my config now: $ appc -v 5.2.1-12 $ alloy -v 1.8.4 $ appc alloy -v 1.7.35 My config before: Node.js Version = 0.12.7 CLI Version = 5.0.6 $ npm -v 2.11.3 $ ti -v 5.0.5 $ alloy -v 1.7.19
  12. Fokke Zandbergen 2016-03-30

    So it worked when you used ti build with Alloy 1.7.19 and it failed when you run via appc run with Alloy 1.7.35?
  13. Anna 2016-03-31

    Yes
  14. Fokke Zandbergen 2016-03-31

    [~amurcia] I ran http://get.fokkezb.nl/_/5mhW77c with both Alloy 1.7.19 and 1.7.35 and both work. I'm using SDK 5.2.1.GA in both cases. Can you verify using the same test case? Please create a new JIRA ticket if you manage to get a reproducible test case.
  15. Anna 2016-03-31

    I'm using SDK 5.1.2.GA
  16. Fokke Zandbergen 2016-03-31

    [~amurcia] just tested both Alloy versions with SDK 5.1.2.GA and still works. Please try to get the linked test case to fail and open a new JIRA ticket if you succeed in failing ;)
  17. Anna 2016-03-31

    ok
  18. Eric Wieber 2016-03-31

    Verified fixed, using: MacOS 10.11.4 (15E65) Studio 4.5.0.201602170821 Ti SDK 5.2.2.v20160328141205 Appc NPM 4.2.5-1 Appc CLI 5.2.2-3 Alloy 1.8.5 Xcode 7.3 (7D175) Missing model attributes no longer cause an error. Tested with provided test case and project provided by a user, in addition to a created test case. No errors encountered and blank strings are rendered instead.

JSON Source