Titanium

[ALOY-867] dataTranform executes twice in Alloy using sql data source

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2013-11-15T22:23:42.000+0000
Affected Version/sn/a
Fix Version/sAlloy 1.3.0, 2013 Sprint 23
ComponentsRuntime
Labelsalloy, dataFilter, qe-port
ReporterKarl Kopp
AssigneeTony Lukasavage
Created2013-10-20T05:32:40.000+0000
Updated2017-10-25T15:36:23.000+0000

Description

Started via developer question: http://developer.appcelerator.com/question/157503/alloy-collection-transform-executes-twice-per-row I used the sample app here: https://github.com/appcelerator/alloy/tree/master/test/apps/models/sql_preload and altered 2 files. index.xml - added the dataTransform call and removed the dataFunction call:
<Alloy>
    <Window>
        <Label id="title" onClick="addTestFighter">Fighters</Label>
        <TableView id="table" dataCollection="fighters" onClick="showId" dataTransform="transformData">
            <Require src="row"/>
        </TableView>
    </Window>
</Alloy>
index.js - added a simple transformData function that just spits out the ID
var fighters = Alloy.Collections.fighters;
var counter = 1;
 
function showId(e) {
    if (e.row.model) {
        alert(e.row.model);
    }
}
 
function addTestFighter(e) {
    // create the test fighter model
    var model = Alloy.createModel('fighters', {
        name: 'Name ' + counter,
        nickname: 'Nickname ' + counter
    });
    counter++;
 
    // add model to the collection and save it to sqlite
    fighters.add(model);
    model.save();
 
    // let's refresh so we can see the ids coming from the
    // autoincrement field in the sqlite database in the
    // row click alerts
    fighters.fetch();
}
 
function transformData(model) {
    var attrs = model.toJSON();
    Ti.API.info('attrs: '+ attrs.id);
    return attrs;
}
 
fighters.fetch();
 
$.index.open();
When I run this I can see the transform function called twice:
[INFO][TiAPI   ( 2072)]  attrs: 1
[INFO][TiAPI   ( 2072)]  attrs: 2
[INFO][TiAPI   ( 2072)]  attrs: 3
[INFO][TiAPI   ( 2072)]  attrs: 4
[INFO][TiAPI   ( 2072)]  attrs: 5
[INFO][TiAPI   ( 2072)]  attrs: 6
[INFO][TiAPI   ( 2072)]  attrs: 7
[INFO][TiAPI   ( 2072)]  attrs: 8
[INFO][TiAPI   ( 2072)]  attrs: 9
[INFO][TiAPI   ( 2072)]  attrs: 10
[INFO][dalvikvm-heap( 2072)] Grow heap (frag case) to 3.390MB for 635808-byte allocation
[INFO][TiAPI   ( 2072)]  attrs: 1
[INFO][TiAPI   ( 2072)]  attrs: 2
[INFO][TiAPI   ( 2072)]  attrs: 3
[INFO][TiAPI   ( 2072)]  attrs: 4
[INFO][TiAPI   ( 2072)]  attrs: 5
[INFO][TiAPI   ( 2072)]  attrs: 6
[INFO][TiAPI   ( 2072)]  attrs: 7
[INFO][TiAPI   ( 2072)]  attrs: 8
[INFO][TiAPI   ( 2072)]  attrs: 9
[INFO][TiAPI   ( 2072)]  attrs: 10
Note - this seems to only happen when using the SQL data source. If you use the in memory data structure it doesn't happen. Eg this seems to work fine: https://github.com/appcelerator/alloy/tree/master/test/apps/models/binding_dataFunction

Comments

  1. Peter Evans 2013-11-05 I suspect that the transform is being called once for each model attribute, not once per model. This is what my logging shows. I have a model with 10 attributes and the transform is being called 10 times. I'm using sqlrest too.
  2. Tony Lukasavage 2013-11-07 This fix was a combination of a fix for the fetch event firing too many times, but also adding some "silent" flags to the save() and add() calls to ensure binding is not triggered too many times. PR: https://github.com/appcelerator/alloy/pull/271 test app: https://github.com/appcelerator/alloy/tree/master/test/apps/models/sql_preload Functional test (run for ios)

    Run the app

    Ensure that the log shows one message from the dataTransform function for each model represented in the UI. Only one message per model.

    Click the title bar. This should add a new model to the collection and add it to the end of the list in the UI.

    Ensure that this event generated only one message from the dataTransform function for each model represented in the UI, exactly like when you initially started.

  3. Tony Lukasavage 2013-11-15 Re-opening due to the fact that this fix caused data binding UI updates not to fire in some cases. Investigating.
  4. Tony Lukasavage 2013-11-15 commit: https://github.com/appcelerator/alloy/commit/5645fc7d4a2852ef3ac6fb789e25f2de52fa8d38 Test the same as originally noted. In addition also run the following test app: https://github.com/appcelerator/alloy/tree/master/test/apps/models/todo

    Ensure that it runs without compile or runtime errors.

    Ensure that when you add, check, or delete items that they are always surrounded by square brackets, which are added in the dataTransform method. Prior to this commit, some of these operations would work, but not show the square brackets around the items.

  5. Federico Casali 2013-12-04 Verified fixed. TiSDK 3.2.0.v20131127194046 CLI 3.2.0-beta Alloy 1.3.0-beta Closing.
  6. Benjamin Koryon 2017-10-25 I'm experiencing a similar issue, where the dataTransform attribute executes every time for each item in the collection. Logging in the dataTransform function proves the fact that it's executing for each item in the collection. Here's my current setup: Operating System Name = Mac OS X Version = 10.12.6 Architecture = 64bit # CPUs = 8 Memory = 16.0GB Node.js Node.js Version = 6.11.4 npm Version = 3.10.10 Appcelerator CLI Installer = 4.2.9 Core Package = 6.2.4 Titanium CLI CLI Version = 5.0.14 node-appc Version = 0.2.41 Titanium SDKs 6.2.2.GA Version = 6.2.2 Install Location = Platforms = iphone, android, mobileweb git Hash = 42c7196 git Timestamp = 9/19/2017 23:07 node-appc Version = 0.2.43

JSON Source