Bound variable not updating view automatically

I have a $scope variable that is bound to the results of a database query. When the view loads, the query runs and the variable is updated but the view does not refresh.

When I touch/click the navigation bar the view appears to reload and the list is drawn correctly with the expected data.

Controller

.controller("MyTicketsCtrl", ['$scope','$http','$stateParams','$ionicLoading',function($scope,$http,$stateParams,$ionicLoading) { 
	
	$scope.tickets = [];
	
	var init = function() {

		var db = window.sqlitePlugin.openDatabase("Tickets", "1.0", "Ticket Storage", -1);
		
		
		db.transaction(function(tx) {

			tx.executeSql("SELECT * FROM TICKETS",[], function(tx, results) {
	 		   for(i=0;i<results.rows.length;i++) {
				   var ticket = results.rows.item(i);
				   $scope.tickets.push(ticket);
	 		   }
			});

		}, function(e) {
	      console.log("ERROR: " + e.message);
	    });
	}
	
	init();
}])

View

<ion-view title="My Tickets">	
	<ion-content class="has-header">
		{{ tickets }}
		<ion-list >
			<ion-item class='item-icon-right' ng-repeat='ticket in tickets' href='#/app/tickets/{{ticket.id}}'>
				<h2>{{ ticket.event_name.truncate() }} @ {{ticket.venue_name}}</h2>
				<h3>{{ ticket.event_date }}</h3>
				{{ ticket.quantity}} x {{ ticket.ticket_type }}
				<i class="pink icon ion-chevron-right icon-accessory"></i>
			</ion-item>
		</ion-list>
	</ion-content>
</ion-view>

Can anyone tell me what is going wrong here?

I have added a success callback to the transaction and can see that $scope.tickets holds an array of tickets as expected, but the view still does not refresh until the nag bar is clicked or touched.

Thanks!

Yes! You should read up to angulars’ $.apply function… You should very rarely use it! Except for the situation where you have timers or other asynchronous functions in a non-angular way. Using angulars $timeout or $http already wraps with $.apply on their own. I’ve found this article very thorough: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Basically, using your piece of code:

Controller:

.controller("MyTicketsCtrl", ['$scope','$http','$stateParams','$ionicLoading',function($scope,$http,$stateParams,$ionicLoading) { 

$scope.tickets = [];

var init = function() {

	var db = window.sqlitePlugin.openDatabase("Tickets", "1.0", "Ticket Storage", -1);


	db.transaction(function(tx) {

		tx.executeSql("SELECT * FROM TICKETS",[], function(tx, results) {
/*****************/$scope.$apply(function(){
 		     for(i=0;i<results.rows.length;i++) {
			   var ticket = results.rows.item(i);
			   $scope.tickets.push(ticket);
 		     }
    /*************/});
		});

	}, function(e) {
      console.log("ERROR: " + e.message);
    });
}

init();
}])

Hopefully I made the changes clear this way :slight_smile:

Thanks iwantwin,

I saw Jim’s article and tried a few approaches.

I have tried to implement your suggestion, but am left with the same situation, nothing being rendered to the screen.

Adam

If you create an alert in the success handler of your executeSql, do you receive the alert? I can only think about the code not being executed then… But I’m pretty new to angular myself, so I might not see something that’s happening :wink: