Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8872] Android: Type error during KS launch

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2012-04-25T13:20:23.000+0000
Affected Version/sRelease 2.1.0
Fix Version/sRelease 2.1.0, Sprint 2012-09 Core
ComponentsAndroid
Labelscore, regression
ReporterAllen Yeung
AssigneeOpie Cyrus
Created2012-04-24T10:29:36.000+0000
Updated2012-06-21T11:46:42.000+0000

Description

Steps to reproduce: 1. Checkout the lastest master build 2. Run KS Expected: KS should run without any errors. Actual: A runtime error occurs as soon as we launch KS: E/TiJSError(28389): (main) [769,1671] ----- Titanium Javascript Runtime Error ----- E/TiJSError(28389): (main) [0,1671] - In app.js:189,29 E/TiJSError(28389): (main) [0,1671] - Message: Uncaught TypeError: Cannot read property 'title' of undefined E/TiJSError(28389): (main) [0,1671] - Source: Ti.API.info('tab ' + e.tab.title + ' prevTab = ' + (e.previousTab ? e.previ

Comments

  1. Opie Cyrus 2012-04-24

    The issue here is not so much a regression in platform behavior as correct behavior exposing previously masked issue with the logic in KS perhaps. Further discussion required to determine the correct way to deal with situation.
  2. Opie Cyrus 2012-04-24

    PR #2069 opened. In order to test the change, temporarily replace the app.js in Kitchen Sink with the one below. When running KS: 1) Select tab 3 and you should see log output of the focus listener attached to the tabgroup and the window for tab 3 2) Select tab 2 and you should see log output of the blur listener attached to the tabgroup and the window for tab 3
       // this sets the background color of the master UIView (when there are no windows/tab groups on it)
       Titanium.UI.setBackgroundColor('#000');
       
       // create tab group
       var tabGroup = Titanium.UI.createTabGroup({id:'tabGroup1'});
       
       
       //
       // create base UI tab and root window
       //
       var win1 = Titanium.UI.createWindow({className:'win1'});
       
       var tab1 = Titanium.UI.createTab({
       	id:'tab1',
       	window:win1
       });
       
       //
       // create controls tab and root window
       //
       var win2 = Titanium.UI.createWindow({
       	url:'main_windows/controls.js',
       	titleid:'controls_win_title'
       });
       var tab2 = Titanium.UI.createTab({
       	icon:'images/tabs/KS_nav_ui.png',
       	titleid:'controls_win_title',
       	window:win2
       });
       
       
       //
       // create phone tab and root window
       //
       var win3 = Titanium.UI.createWindow({
       	url:'main_windows/phone.js',
       	titleid:'phone_win_title'
       });
       win3.addEventListener('focus', function(e) {
       	Ti.API.info("FOCUS EVENT FIRED ON WINDOW: " + e.tab); // e.tab should be undefined
       });
       win3.addEventListener('blur', function(e) {
       	Ti.API.info("BLUR EVENT FIRED ON WINDOW: " + e.index); // e.index should be undefined
       });
       var tab3 = Titanium.UI.createTab({
       	icon:'images/tabs/KS_nav_phone.png',
       	titleid:'phone_win_title',
       	window:win3
       });
       
       
       //
       // create platform tab and root window
       //
       var win4 = Titanium.UI.createWindow({
       	url:'main_windows/platform.js',
       	titleid:'platform_win_title'
       });
       var tab4 = Titanium.UI.createTab({
       	icon:'images/tabs/KS_nav_platform.png',
       	titleid:'platform_win_title',
       //	Commented out as per 1773
       //	active:true,
       	window:win4
       });
       
       //
       // create mashup tab and root window
       //
       var win5 = Titanium.UI.createWindow({
       	url:'main_windows/mashups.js',
       	titleid:'mashups_win_title'
       });
       var tab5 = Titanium.UI.createTab({
       	icon:'images/tabs/KS_nav_mashup.png',
       	titleid:'mashups_win_title',
       	window:win5
       });
       
       //
       //  add tabs
       //
       tabGroup.addTab(tab1);
       tabGroup.addTab(tab2);
       tabGroup.addTab(tab3);
       tabGroup.addTab(tab4);
       tabGroup.addTab(tab5);
       
       tabGroup.addEventListener('open',function()
       {
       	// set background color back to white after tab group transition
       	Titanium.UI.setBackgroundColor('#fff');
       });
       
       tabGroup.setActiveTab(1);
       // open tab group with a transition animation
       tabGroup.open({
       	transition: Titanium.UI.iPhone && Titanium.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT
       });
       
       // setTimeout(function()
       // {
       	// tabGroup.close({
       		// transition:Titanium.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT
       	// });
       // },2000);
       
       
       //
       //  TAB GROUP EVENTS
       //
       var messageWin = Titanium.UI.createWindow({
       	height:30,
       	width:250,
       	bottom:70,
       	borderRadius:10,
       	touchEnabled:false,
       
       	orientationModes : [
       	Titanium.UI.PORTRAIT,
       	Titanium.UI.UPSIDE_PORTRAIT,
       	Titanium.UI.LANDSCAPE_LEFT,
       	Titanium.UI.LANDSCAPE_RIGHT
       	]
       });
       var messageView = Titanium.UI.createView({
       	id:'messageview',
       	height:30,
       	width:250,
       	borderRadius:10,
       	backgroundColor:'#000',
       	opacity:0.7,
       	touchEnabled:false
       });
       
       var messageLabel = Titanium.UI.createLabel({
       	id:'messagelabel',
       	text:'',
       	color:'#fff',
       	width:250,
       	height:'auto',
       	font:{
       		fontFamily:'Helvetica Neue',
       		fontSize:13
       	},
       	textAlign:'center'
       });
       messageWin.add(messageView);
       messageWin.add(messageLabel);
       
       //
       // TAB EVENTS
       //
       
       // tab group close event
       tabGroup.addEventListener('close', function(e)
       {
       	messageLabel.text = 'tab group close event';
       	messageWin.open();
       	if (Ti.Platform.osname == "iphone") {
       //On iOS, when we're closing the tab group, this is a result
       //of the tab group example of 'Close/Animate Tab Group' and
       //we want to reopen the tab group so the user can continue with
       //using Kitchen Sink. HOWEVER, on Android, this is also triggered
       //when the app is being closed via back button, where reopening
       //the tab group is not desired. This is purely a quirk of the tests.
       		tabGroup.open();
       	}
       	setTimeout(function()
       	{
       		messageWin.close({opacity:0,duration:500});
       	},1000);
       });
       
       
       // tab group open event
       tabGroup.addEventListener('open', function(e)
       {
       	messageLabel.text = 'tab group open event';
       	messageWin.open();
       	setTimeout(function()
       	{
       		messageWin.close({opacity:0,duration:500});
       	},1000);
       
       });
       
       // focus event listener for tracking tab changes
       tabGroup.addEventListener('focus', function(e)
       {
       	messageLabel.text = 'tab changed to ' + e.index + ' old index ' + e.previousIndex;
       	messageWin.open();
       	setTimeout(function()
       	{
       		Ti.API.info('tab ' + e.tab.title  + ' prevTab = ' + (e.previousTab ? e.previousTab.title : null));
       		messageLabel.text = 'active title ' + e.tab.title + ' old title ' + (e.previousTab ? e.previousTab.title : null);
       	},1000);
       
       	setTimeout(function()
       	{
       		messageWin.close({opacity:0,duration:500});
       	},2000);
       
       });
       
       // blur event listener for tracking tab changes
       tabGroup.addEventListener('blur', function(e)
       {
       	Titanium.API.info('tab blur - new index ' + e.index + ' old index ' + e.previousIndex);
       });
       
       
       //
       //   CUSTOM EVENTS
       //
       Titanium.App.addEventListener('event_one', function(e)
       {
       	messageLabel.text = 'app.js: event one, array length = ' + e.data.length;
       	messageWin.open();
       	setTimeout(function()
       	{
       		messageWin.close({opacity:0,duration:500});
       	},1000);
       });
       
       Titanium.App.addEventListener('event_two', function(e)
       {
       	messageLabel.text = 'app.js: event two, name = ' + e.name;
       	messageWin.open();
       	setTimeout(function()
       	{
       		messageWin.close({opacity:0,duration:500});
       	},1000);
       
       });
       
       //
       //  CREATE CUSTOM LOADING INDICATOR
       //
       var indWin = null;
       var actInd = null;
       function showIndicator()
       {
       	if (Ti.Platform.osname != 'android')
       	{
       		// window container
       		indWin = Titanium.UI.createWindow({
       			height:150,
       			width:150
       		});
       
       		// black view
       		var indView = Titanium.UI.createView({
       			height:150,
       			width:150,
       			backgroundColor:'#000',
       			borderRadius:10,
       			opacity:0.8
       		});
       		indWin.add(indView);
       	}
       
       	// loading indicator
       	actInd = Titanium.UI.createActivityIndicator({
       		style:Titanium.UI.iPhone && Titanium.UI.iPhone.ActivityIndicatorStyle.BIG,
       		height:30,
       		width:30
       	});
       
       	if (Ti.Platform.osname != 'android')
       	{
       		indWin.add(actInd);
       
       		// message
       		var message = Titanium.UI.createLabel({
       			text:'Loading',
       			color:'#fff',
       			width:'auto',
       			height:'auto',
       			font:{fontSize:20,fontWeight:'bold'},
       			bottom:20
       		});
       		indWin.add(message);
       		indWin.open();
       	} else {
       		actInd.message = "Loading";
       	}
       	actInd.show();
       
       }
       
       function hideIndicator()
       {
       	actInd.hide();
       	if (Ti.Platform.osname != 'android') {
       		indWin.close({opacity:0,duration:500});
       	}
       }
       
       //
       // Add global event handlers to hide/show custom indicator
       //
       Titanium.App.addEventListener('show_indicator', function(e)
       {
       	Ti.API.info("IN SHOW INDICATOR");
       	showIndicator();
       });
       Titanium.App.addEventListener('hide_indicator', function(e)
       {
       	Ti.API.info("IN HIDE INDICATOR");
       	hideIndicator();
       });
       
       // trap app shutdown event
       Titanium.App.addEventListener('close',function(e)
       {
       	Ti.API.info("The application is being shutdown");
       });
       
       // test for loading in a root-level include
       Ti.include("welcome.js");
       
       // test out logging to developer console, formatting and localization
       Ti.API.info(String.format("%s%s",L("welcome_message","default_not_set"),Titanium.version));
       Ti.API.debug(String.format("%s %s",L("user_agent_message","default_not_set"),Titanium.userAgent));
       
       Ti.API.debug(String.format("locale specific date is %s",String.formatDate(new Date()))); // default is short
       Ti.API.debug(String.format("locale specific date (medium) is %s",String.formatDate(new Date(),"medium")));
       Ti.API.debug(String.format("locale specific date (long) is %s",String.formatDate(new Date(),"long")));
       Ti.API.debug(String.format("locale specific time is %s",String.formatTime(new Date())));
       Ti.API.debug(String.format("locale specific currency is %s",String.formatCurrency(12.99)));
       Ti.API.debug(String.format("locale specific decimal is %s",String.formatDecimal(12.99)));
       
       
       Ti.API.info("should be en, was = "+Ti.Locale.currentLanguage);
       Ti.API.info("welcome_message = "+Ti.Locale.getString("welcome_message"));
       Ti.API.info("should be def, was = "+Ti.Locale.getString("welcome_message2","def"));
       Ti.API.info("welcome_message = "+L("welcome_message"));
       Ti.API.info("should be def, was = "+L("welcome_message2","def"));
       Ti.API.info("should be 1, was = "+String.format('%d',1));
       Ti.API.info("should be 1.0, was = "+String.format('%1.1f',1));
       Ti.API.info("should be hello, was = "+String.format('%s','hello'));
       
       // test to check that we can iterate over titanium based objects
       (function(){
       	Ti.API.info("you should see a list of properties (3 or more) below this line");
       	Ti.API.info("---------------------------------------------------------------");
       	for (var p in win1)
       	{
       		Ti.API.info("         win1 property: "+p);
       	}
       	Ti.API.info("Did you see properties? ^^^^^ ");
       	Ti.API.info("---------------------------------------------------------------");
       
       	Ti.API.info("you should see a list of modules (3 or more) below this line");
       	Ti.API.info("---------------------------------------------------------------");
       	for (var p in Titanium)
       	{
       		Ti.API.info("             module: "+p);
       	}
       	Ti.API.info("Did you see modules? ^^^^^ ");
       	Ti.API.info("---------------------------------------------------------------");
       })();
       
       
       Ti.include("examples/version.js");
       
       if (isiOS4Plus())
       {
       	// register a background service. this JS will run when the app is backgrounded
       	var service = Ti.App.iOS.registerBackgroundService({url:'bg.js'});
       
       	Ti.API.info("registered background service = "+service);
       
       	// listen for a local notification event
       	Ti.App.iOS.addEventListener('notification',function(e)
       	{
       		Ti.API.info("local notification received: "+JSON.stringify(e));
       	});
       
       	// fired when an app resumes for suspension
       	Ti.App.addEventListener('resume',function(e){
       		Ti.API.info("app is resuming from the background");
       	});
       	Ti.App.addEventListener('resumed',function(e){
       		Ti.API.info("app has resumed from the background");
       	});
       
       	Ti.App.addEventListener('pause',function(e){
       		Ti.API.info("app was paused from the foreground");
       	});
       }
       
       if (Ti.App.Properties.getBool('showNotice', true)){
       	var alertNotice = Ti.UI.createAlertDialog({
       		buttonNames: ['OK', 'Visit docs', 'Don\'t show again'],
       		cancel:0,
       		title: 'Notice',
       		message: 'While this KitchenSink provides an extensive demonstration of the Titanium API, its structure is not recommended for production apps. Please refer to our documentation for more details.'
       	});
       	alertNotice.show();
       	alertNotice.addEventListener('click', function(e){
       		if(e.index === 1){
       			Titanium.Platform.openURL('http://wiki.appcelerator.org/display/guides/Example+Applications');
       		}
       		if(e.index === 2){
       			Ti.App.Properties.setBool('showNotice', false);
       		}
       	});
       }
       
  3. Eric Merriman 2012-06-21

    Verified no longer producing type error on launch. Also verified blur/focus events with sample code provided. Used SDK 2.1.0.v20120618154152.

JSON Source