Jigar Naik
Jigar Naik

Reputation: 1994

Ionic ion-list does not display result without tap/click

Framwwork : Ionic & Angualr-JS

I have two search text-box on screen as displayed in the attached image. When the value of both the text-boxes are populated, it search for result and populate array for display on ion-list.

The problem i am facing is the array is populated but it does not updated view. When i tap or click on the screen it displays the ion-list with the expected result as shown in the attached screen shot.

The same thing is happening for couple of other screens. My ionic html page has become complex since i am using the same html page to display other components for other pages.

There are lot of ng-show & ng-if conditions.

Right now it should displayed search result, but it's not displaying as in screenshot.

After tapping or clicking the screen area, it displays search result which is not correct

html code

<!-- Source search text-box -->
<ion-header-bar class="bar-subheader item-input-inset">
    <label class="item-input-wrapper">
        <i class="icon ion-search placeholder-icon"></i>
        <input type="search" placeholder="Choose starting point..." ng-change="searchSourceStation()" ng-model="data.sourceStation">
    </label>
    <button class="button button-clear" ng-click="clearSource();">Cancel</button>
</ion-header-bar>
<!-- destination search text-box -->
<ion-header-bar class="bar-subheader item-input-inset">
    <label class="item-input-wrapper">
        <i class="icon ion-search placeholder-icon"></i>
        <input type="search" placeholder="Choose destination..." ng-change="searchDestinationStation()" ng-model="data.destinationStation">
    </label>
    <button class="button button-clear" ng-click="clearDestination();">Cancel</button>
</ion-header-bar>
<ion-content class="has-subheader"> 
    <ion-list class="list has-header"> 
        <!--  to display bus/train list on key press of source and dest textbox -->
        <ion-item class="item" ng-repeat="station in data.stations" type="item-text-wrap" ng-click="setSourceOrDestination(station.stationName);"> 
            <p>{{station.stationName}}</p>
        </ion-item>
    </ion-list> 

    <div ng-show="showScroll" style="background-color: lightblue;">
        <ion-infinite-scroll on-infinite="loadMore()" distance="10%" ng-if="!noData"></ion-infinite-scroll>
    </div>

    <!--  To Display History of past Search -->     
    <ion-list class="list has-header" ng-if="showHistory"> 
        <ion-item class="item item-icon-left item-icon-right" ng-repeat="trainHistory in history track by $index" ng-click="setSourceAndDestination('{{trainHistory.trainHistory.sourceStation}}','{{trainHistory.trainHistory.destinationStation}}')" > 
            <i class="icon ion-ios-clock-outline" style="font-size: 30px"></i>
            <p>{{trainHistory.trainHistory.sourceStation }} to {{trainHistory.trainHistory.destinationStation }} </p>
            <i class="icon ion-arrow-graph-up-left" style="font-size: 30px" ng-click="filterTrains"></i>
        </ion-item>
    </ion-list> 
    <ion-list class="list has-header" ng-if="message">
          <ion-item class="item-stable">
                <div class="form-error" style="text-align: center;font-size: 14px;">{{message}}</div>
          </ion-item>
    </ion-list>
    <!-- Search result ion-list -->
    <ion-list class="list has-header" ng-if="transport.code != 'BUS'">

        <!-- this won't get displayed for the attached screenshot -->
        <ion-item class="item item-divider item-icon-right" ng-if="showFilter">
            <p>Total Trains {{filteredTrain.length}}</p>
            <input type="hidden" ng-model="slowFastFlag" />
            <a class="icon ion-more" ng-click="popover.show($event)"></a>
            <input type="hidden" ng-model="filterText" />
        </ion-item>

        <div ng-repeat="train in filteredTrain = (data.trains | filter: slowFastFlag)">
          <!-- this won't get displayed for the attached screenshot -->
          <ion-item class="item-stable" ng-click="toggleGroup(train);" ng-class="{active: isGroupShown(train)}">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                        <tr>
                            <td ng-if="train.trainName != null"><h3>{{train.trainName}}</h3></td>
                            <td style="font-size: 12px;" align="right" ng-if="train.sourceStationArrivalTime"><i class="icon ion-clock"></i>{{" " + train.sourceStationArrivalTime | limitTo: 6 }}</td>
                        </tr>
                        <tr>
                            <td ng-if="train.arrivingIn != null"><p><i class="icon ion-ios-stopwatch"></i><font color="green"> In {{train.arrivingIn }}</font></p></h2></td>
                            <td style="font-size: 12px;" align="right" ng-if="train.destinationStationArrivalTime != null"><i class="icon ion-clock"></i>{{" " + train.destinationStationArrivalTime | limitTo: 6 }}</td>
                        </tr>
                    </table>
          </ion-item>
          <!-- This is search result. -->
          <ion-item class="item-accordion" ng-repeat="station in train.stations" ng-show="isGroupShown(train)" ng-click="toggleGroup(train);">
                <table border="1" cellpadding="0" cellspacing="0" width="100%">
                        <tr>
                            <td align="left" style="font-size: 28px;width: 30px;" ng-if="station.lineColour != null">
                                <i class="ion-android-subway yellow" ng-if="station.lineColour == 'YELLOW'"></i>
                                <i class="ion-android-subway red" ng-if="station.lineColour == 'RED'"></i>
                                <i class="ion-android-subway green" ng-if="station.lineColour == 'GREEN'"></i>
                                <i class="ion-android-subway blue" ng-if="station.lineColour == 'BLUE'"></i>
                                <i class="ion-android-subway skyBlue" ng-if="station.lineColour == 'SKY_BLUE'"></i>
                                <i class="ion-android-subway orange" ng-if="station.lineColour == 'ORANGE'"></i>
                            </td>
                            <td align="left" valign="middle" style="vertical-align: middle;">
                                <h3>{{station.stationName}}</h3>
                            </td>
                            <td style="font-size: 12px;" align="right" ng-if="station.arrivalTime != null">
                                <i class="icon ion-clock"></i>{{" " + station.arrivalTime | limitTo: 6 }}
                            </td>
                        </tr>
                    </table>
          </ion-item>
        </div>
  </ion-list>

Angular-js function call when user enters value in both the text-boxes

$scope.findUpcomingTrains = function() {
    console.log("findUpcomingTrains");
    $scope.profile = JSON.parse($window.localStorage['profile']);
    var promise = TrainService.findUpcomingTrains($scope.transport.code, $scope.data.sourceStation, $scope.data.destinationStation, $scope.profile.city);
    promise.then(function(resp) {
        $scope.data.trains = resp.data.trains;
        if ($scope.transport.code == 'LOCAL') {
            $scope.showFilter = true;
        }
        $scope.showHistory = false;

        if ($scope.data.sourceStation != $scope.data.destinationStation) {
            if ($scope.transport.code == 'MONO') {
                $scope.addToMonoHistory($scope.data.sourceStation, $scope.data.destinationStation, $scope.profile.city);
            }

            if ($scope.transport.code == 'METRO') {
                $scope.addToMetroHistory($scope.data.sourceStation, $scope.data.destinationStation, $scope.profile.city);
            }
            if ($scope.transport.code == 'LOCAL') {
                $scope.addToLocalHistory($scope.data.sourceStation, $scope.data.destinationStation, $scope.profile.city);
            }
        }


        if (resp.data.message) {
            $scope.message = resp.data.message;
        } else {

        }
    }, function(resp) {
        console.log("ERROR : " + resp);
    })
    console.log("findUpcomingTrains : $scope.$apploy() called")
}

One more observation is that this issue only occurs when the user uses ion-infinite-scroll, which means tries to scroll down and it calls loadMore() function of infinite scroll.

Below is my loadMore function

$scope.loadMore = function() {
      $scope.dataToLoad = 15;
      console.log("******* loadmore() ******* : No Data : " + $scope.noData);

      if (angular.isUndefined($scope.data.stations)) {
          console.log("$scope.data.stations is undefined...");
          $scope.noData = false;
          $scope.$broadcast('scroll.infiniteScrollComplete');
          return;
      }
      console.log("loadMore : $scope.data.filteredStations : " + $scope.data.stations.length + " , $scope.dataToLoad " + $scope.dataToLoad);
      $scope.data.stations = $scope.data.filteredStations.slice(0, ($scope.data.stations.length + $scope.dataToLoad));

      if ($scope.data.stations.length == $scope.data.filteredStations.length) {
          $scope.noData = true;
      } else {
          $scope.noData = false;
      }
      $scope.$broadcast('scroll.infiniteScrollComplete');
  }

Upvotes: 0

Views: 1361

Answers (1)

Dave
Dave

Reputation: 5416

I too had this issue. There was a bug in one of the Angular 2 releases that caused this. Assuming this is related, the workaround was to use ngZone:

zone.run(() => {
    // do stuff here...
});

But since the framework was updated, that should no longer be necessary.

Upvotes: 0

Related Questions