"refreshing" ion-list from the result of async http call


#1

Hi All,

I have a basic question on “refreshing” ion-list from the result of async http call.

How can I set an variable foundUsers which is a result of an async call in an ion-list ?

The template:

<ion-view title="XX'">
<div class="bar bar-subheader item-input-inset">
        <label class="item-input-wrapper">
            <i class="icon ion-ios7-search placeholder-icon"></i>
            <input id="search" type="search" placeholder="Search" ng-model="model.search" autocorrect="off" >                
        </label>
        <button class="button button-clear" ng-click="searchUser()">Search</button>            
</div>

<ion-content has-header="true" has-tabs="true">
    <h3>Search results:</h3>
    <ion-list>
        <ion-item ng-repeat="user in foundUsers" type="item">
            <h3>{{user.username}}</h3>
        </ion-item>            
    </ion-list>
</ion-content>

The controller:

.controller('FriendCtrl', function($scope, $state, $stateParams, FriendService) {
$scope.model = {username:"", search:""};
$scope.$watch("foundUsers", function(newValue, oldValue){            
        alert("test"); // why alert only after the second click to Search button? 
    });
    
    $scope.searchUserCallBack = function(foundUsers) {  
        alert(JSON.stringify(foundUsers));
        $scope.foundUsers=foundUsers.users;
}

    $scope.searchUser = function() {            
        var output = FriendService.searchUser($scope.model.search, $state, $scope.searchUserCallBack); // an async call that finally sets the foundUsers variable using the callback.
}

Thank you in advance for your help.

Cheers.


#2

My first suggestion would be to not use the callbacks. Using Angulars $q promise library would make things a lot simpler. So, your “FriendService” would return a promise. Then, your controller would use the .then method to put the results on the scope after the promise completes.

If that’s not familiar territory, I’d suggest watching the Egghead.io videos. They’re really helpful.

Other than that, what is the exact problem right now? When you type in the search field and click “Search”:

  • Do you get results from “FriendService”?
  • Does the $scope.searchuserCallBack get called?
  • Does your list not update with the results?

If item 1 & 2 are working and item 3 is not working, I’m guessing it’s because you aren’t using “dot notation”.

If so, try this:

<ion-content has-header="true" has-tabs="true">
    <h3>Search results:</h3>
    <ion-list>

        <ion-item ng-repeat="user in data.foundUsers" type="item">  <!-- NOT THE DOT NOTATION! -->
            <h3>{{user.username}}</h3>
        </ion-item>            
    </ion-list>
</ion-content>
.controller('FriendCtrl', function($scope, $state, $stateParams, FriendService) {
$scope.model = {username:"", search:""};

$scope.data = {
    "foundUsers" : []  // INITIALLY SET FOUND USERS TO AN EMPTY ARRAY
};

$scope.$watch("foundUsers", function(newValue, oldValue){            
        alert("test"); // why alert only after the second click to Search button? 
    });

    $scope.searchUserCallBack = function(foundUsers) {  
        alert(JSON.stringify(foundUsers));
        $scope.data.foundUsers=foundUsers.users;  // NOW SET FOUNDUSERS TO THE NEW DATA.  NOTE THE DOT NOTATION.
}

    $scope.searchUser = function() {            
        var output = FriendService.searchUser($scope.model.search, $state, $scope.searchUserCallBack); // an async call that finally sets the foundUsers variable using the callback.
}

#3

Hi @Calendee,

Thanks a lot, I followed your first suggestion and it is working fine.

Btw, all your 3 questions answers are yes-es, hence it is not “dot notation” problem. Nevertheless I tried it anyway and it does not worked.

Thanks again.


#4

So a bit confused by the current status. It sounds like in some ways its “working fine” and in others “it does not work”. So, are you fixed or not?

If not, you’d probably better post a CodePen sample so we can see what’s going on.


#5

Yes @Calendee, it works with using Angulars $q promise library. Thanks.


#6

I have the same problem, I tried the promises, but the list is getting rendered before the AJAX call end.

Here is the code:


#7

Hi,

I don’t see explicitly $q promise library usage in your code.

FYI, I use the library directly: using
var deferred = $q.defer();


//if OK -
deferred.resolve(
//if NOK -
deferred.reject( … )

return deferred.promise;

also I am using … var client = new XMLHttpRequest(); instead of $http.jsonp (i think this is sync??).

Cheers,
bmine


#8

I appreciate if you can send me a detailed example


#9

Hi,

Check out this example from Christophe Coenraets:
http://coenraets.org/blog/2014/02/sample-mobile-application-with-ionic-and-angularjs/

you can see it this file how to use the promises lib:

For example the following function:
findById: function(employeeId) {
var deferred = $q.defer();
var employee = employees[employeeId - 1];
deferred.resolve(employee);
return deferred.promise;
}

Actually the promise library is not required in this function, yet it was made like this so you can easily extend to use REST call instead of the in memory array access.

try to replace this line:
var employee = employees[employeeId - 1];

with REST or WebSQL call.

Cheers