Rifki
Rifki

Reputation: 3530

$http request and ng-repeat loop

I'm currently playing around with Angularjs and create a simple app to check domain availability. The scenario is: when user entering search query and submit the form, it will request a list of domains in JSON format, then loop the result using ng-repeat and check the availability one by one but it always give me an errors that refer to https://errors.angularjs.org/1.3.15/$rootScope/infdig?p0=10&p1=%5B%5D

The problem is triggered by checkAvailability, trying to figure it my self for hours but still couldn't find the solution. Hope someone here could help me.

Here is my controller:

app.controller('main', ['$scope', '$http',
    function ($scope, $http) {

        $scope.searchResults = null;

        $scope.search = function () {
            $http.get('/api/domain/search?q=' + this.query).success(function (data) {
                $scope.searchResults = data;
            });
        };

        $scope.checkAvailability = function (domain) {
            // return true;
            $http.get('/api/domain/check?domain=' + domain).success(function (data) {
                return data;
            });
        };

    }
]);

example API response

#http://localhost/api/domain/search

[
    {
        "domain":"exampledomain1.com",
        "tld":"com"
    },
    {
        "domain":"exampledomain2.com",
        "tld":"com"
    },
    {
        "domain":"exampledomain3.com",
        "tld":"com"
    },
    {
        "domain":"exampledomain4.com",
        "tld":"com"
    }
]

#http://localhost/api/domain/check

"available" or "unavailable"

and here is my HTML

<div class="container" ng-controller="main">
    <form class="domain-search form mb40" ng-submit="search()">
        <div class="input-group">
            <input type="text" ng-model="query" class="form-control">
            <span class="input-group-btn">
                <input type="submit" class="btn btn-primary" value="Search">
            </span>
        </div>
    </form>

    <ul ng-if="searchResults">
        <li ng-repeat="item in searchResults">{{ item.domain }} is {{ checkAvailability(item.domain) }}</li>
    </ul>
</div>

Thank you!

Upvotes: 1

Views: 1139

Answers (1)

Dylan Watt
Dylan Watt

Reputation: 3387

In general, this isn't going to work as architected. checkAvailability is a function that always returns undefined. Sure, you make a $http request in there, but you don't return anything. Even if you tried to return something, it'd only be the $http promise, as it hasn't returned yet (async).

I'd deal with all the data fetches together. Note it'd be better to do all this on the backend and surface one call. All these extra ajax calls to get each domain are wasteful.

app.controller('main', ['$scope', '$http', '$q',
    function ($scope, $http, $q) {

        $scope.searchResults = null;

        $scope.search = function () {
            $http.get('/api/domain/search?q=' + this.query).success(function (searchResponse) {
                var promises = [];
                for (var i = searchResponse.length - 1; i >= 0; i--) {
                    (function(i){
                        promises.push($http.get('/api/domain/check?domain=' + searchResponse[i].domain)
                            .then(function(domainResponse){
                                searchResponse[i].availabilty = domainResponse.data;
                            }, function(){console.error(searchResponse[i].domain)}));

                    })(i)

                };

                $q.all(promises).then(function(){
                    $scope.searchResults = searchResponse;

                })

            });
        };
    }
]);

--

<div class="container" ng-controller="main">
<form class="domain-search form mb40" ng-submit="search()">
    <div class="input-group">
        <input type="text" ng-model="query" class="form-control">
        <span class="input-group-btn">
            <input type="submit" class="btn btn-primary" value="Search">
        </span>
    </div>
</form>

<ul ng-if="searchResults">
    <li ng-repeat="item in searchResults">{{ item.domain }} is {{ item.availability }}</li>
</ul>

Upvotes: 2

Related Questions