Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25662] Large collection retrieved by restapi breaks in model.fetch with: "Maximum call stack size exceeded." at backbone.js (line 625)

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionCannot Reproduce
Resolution Date2019-11-06T22:35:29.000+0000
Affected Version/sRelease 7.0.0, Release 7.0.1
Fix Version/sn/a
ComponentsiOS
Labelsregression
ReporterJohn Dalsgaard
AssigneeShak Hossain
Created2018-01-10T18:49:05.000+0000
Updated2019-11-06T22:35:29.000+0000

Description

After updating from SDK 6.3.0 to 7.0.1 I have encountered a problem when fetching data from a backend service using models. When I fetch a little over 46K elements (JSON) via the service everything works. Fetching more than 49K elements it breaks with: {quote}[ERROR] : Script Error { [ERROR] : column = 14; [ERROR] : line = 625; [ERROR] : message = "Maximum call stack size exceeded."; [ERROR] : sourceURL = "file:///Users/jda/Library/Developer/CoreSimulator/Devices/8C57F4CE-45BB-42BF-A384-19DADC911651/data/Containers/Bundle/Application/622094F1-60C4-4507-B122-5AC148B43C68/Test.app/alloy/backbone.js"; {quote} If I change back to 6.3.0 then it works fine also with the larger file set. I have created to temporary service urls (as long as needed for this jira) that can be used to get these data (first is the smaller set): * https://test.dalsgaard-data.dk/jira1.nsf/service.xsp?open&command=getLocationPoints * https://test.dalsgaard-data.dk/jira2.nsf/service.xsp?open&command=getLocationPoints I have created a simple app that can be used to test this. This is index.xml:
<Alloy>
	<Window id="main">
	    <View height="Ti.UI.SIZE">
	        <Label id="language" left="10" top="20"/>
	    </View>
	    <View height="Ti.UI.SIZE">
	        <Label id="label4" left="10" top="10"/>
	    </View>
	    <View height="Ti.UI.SIZE">
	        <Label id="label5" left="10" top="10"/>
	    </View>
	    <Button id="button1" title="Load small" onClick="loadDataSmall"></Button>
	    <Button id="button2" title="Load large" onClick="loadDataLarge"></Button>
	</Window>
</Alloy>
and this is index.js:
function loadData(url){
	var dtStart = new Date();
	$.label4.text = "Load data...";
	console.info("Load data using url: " + url);
	var model = Alloy.createCollection('LocationPoint');
    model.fetch({
        timeout: 20000, 
        url : url,
        success: function(result){
            console.info("loadData: data received");
		    var added = 0;
            for (var k = 0; k < result.length; k++) {
                var key = result.models[k].get("key");
                var record = result.models[k].attributes;
                added++;
            };
            console.info("loadData: " + added + ' records added ');
			var dtNow = new Date();
        	$.label4.text = "Load took " + (dtNow.getMilliseconds() - dtStart.getMilliseconds()) + " ms";
        	$.label5.text = added + " records loaded";
        },
        error: function(result, e){
            console.error("loadData: Error: " + e);
        	$.label4.text = "Load error: " + e;
        }
    }); // Grab data 
}

function loadDataSmall(){
	loadData("https://test.dalsgaard-data.dk/jira1.nsf/service.xsp?open&command=getLocationPoints");
}

function loadDataLarge(){
	loadData("https://test.dalsgaard-data.dk/jira2.nsf/service.xsp?open&command=getLocationPoints");
}

// Init using self executing function
(function (){
	$.language.text = "Test loading large collections";
	$.main.open();
})();
and finally the model "LocationPoint":
exports.definition = {
	config: {
        parentNode : "data",
        URL: "https://test.dalsgaard-data.dk/kunder/dtu/fangst.nsf/service.xsp?open&command=getLocationPoints",
        adapter : {
            type : "restapi",
            collection_name : "LocationPoint",
            idAttribute : "id",			// Not in data from service

            // optimise the amount of data transfer from remote server to app
            addModifedToUrl: true,
            lastModifiedColumn: "created"
        }
    },
	extendModel: function(Model) {
		_.extend(Model.prototype, {
			// extended functions and properties go here
		});

		return Model;
	},
	extendCollection: function(Collection) {
		_.extend(Collection.prototype, {
			// extended functions and properties go here
		});

		return Collection;
	}
};
I use the Rest API driver by Mads Møller from Napp ApS (I have attached the js file to be put in "app/assets/alloy/sync" I you set up this app using 7.0.1 (in tiapp.xml) then pressing button [Load small] will work and [Load larger] will fail with the error above. If you change to 6.3.0 it will work.... Can I change my code to cater for this? _PS. Sorry for the formatting - the editor really is a challenge.... :_(_

Attachments

FileDateSize
restapi.js2018-01-10T17:53:02.000+000013291

Comments

  1. Sharif AbuDarda 2018-01-11

    Hello, Please create a sample test app which generates the issue and attach the project in here. We will test the issue. Thanks.
  2. John Dalsgaard 2018-01-11

    Hi Sharif Well, that is exactly what I did - the source code is so simple that I provided you with the bits and pieces to create a new Alloy project (which by the way I can find NO way to do in Studio!!! - we could earlier!!). And I have also created two external services that the provided code calls for you to test (on one of my servers). Please let me know what you need more? /John
  3. John Dalsgaard 2018-01-11

    .... you may need to edit my message to get the right source code out - as per my comments at the end. I could not format the source code correctly... Or let me know how I can format it in the editor in the browser?
  4. John Dalsgaard 2018-01-11

    Thanks Ewan for the edits! (y) The code tag does not seem to be among the styles in the editor :) Sharif, I guess that you can just take my very simple code from above and reproduce the error. Otherwise, let me know. /John
  5. Ewan Harris 2018-01-11

    I'm only able to reproduce this issue when setting run-on-main-thread to false with the below setup, therefore I don't believe this is an alloy issue so moving to TIMOB. I also observed that using backbone 1.1.2 instead of the default 0.9.2 fixes the issue for me Ti SDK: 7.0.1.GA. 7.0.0.GA Appc CLI: 7.0.1 Alloy: 1.10.10 (backbone 0.9.2) iOS 11.2 Simulator
  6. John Dalsgaard 2018-01-11

    Thanks Ewan! Interesting.... So what do you suggest I should try here in my environment? This is not a "new" app so some of the settings may not be "best practice" now. I am not sure whether I should set run-on-main-thread - and what other consequences for my app that could have? What steps should I use if I want the "supported" way of installing backbone 1.1.2 instead of 0.9.2? Just using
    npm install - g ....
    /John
  7. Ewan Harris 2018-01-12

    [~jda] For backbone, there's a migration guide at http://docs.appcelerator.com/platform/latest/#!/guide/Alloy_Backbone_Migration, to switch to using it you just need to add "backbone": "1.1.2" in your config.json As for the run-on-main-thread setting, I'm not massively familiar with the nuances sorry, [~hknoechel] do you know of any potential issues
  8. John Dalsgaard 2018-01-15

    Ewan, I have played a little with the options you mentioned. 1. Using a newer backbone gave me another error from backbone about a "cid".... 2. Run-on-main-thread The latter is interesting as my first impression is that it runs faster! E.g. loading the data from the server is a little faster - and who don't want "faster"? :-) However, when I open a function with a map (using ti.map) then everything gets veryyyy sloooooowwww..... I think it has more to do with getting the location (in the simulator right now). Is that anything you have seen? Could there be related settings for location services while setting Run-on-main-thread? I'll do some further tests - but just wanted to give some feedback along the way.
  9. John Dalsgaard 2018-01-15

    Could issues like the above be related to using a dispatcher (as described in [an article by Fokke](http://www.tidev.io/2014/09/10/the-case-against-ti-app-fireevent-2/) a couple of years ago)? I use that heavily.... - and testing on an iPhone 7 the delay for getting the gps location is _workable_ - However, it just hang the app somewhere else (seemed arbitrary) Hmmm.... tried again. And it misbehaves the same way as in the simulator on second try. So quite sure it is something that I do in the app that makes it behave like this - but I have no clue as to where to search. Just guessing that it could be related to: ti.map, locationservices and/or perhaps more likely dispatchers...
  10. John Dalsgaard 2018-03-21

    I'll remove the two test services as there seem to be no development on this issue...
  11. John Dalsgaard 2018-06-27

    I have removed the test services now :-(
  12. Alan Hutton 2019-11-06

    Closing issue as “Cannot Reproduce”. No test code provided, or code provided in URL links are no longer available. The SDKs listed are out of date with our current release (8.2.1.GA as of the date of closure), and out of date with mobile OS versions. Updating the code may not reproduce the issue reported, or be a valid test case. If community members feel that the issue is still valid, please add a comment, and include code that demonstrates/reproduces the issue.

JSON Source