2015-04-27 2 views
2
var app = angular.module('app',['ui.bootstrap']); 

app.controller("ListCtrl", function ($scope, $http) { 

    $scope.submit = function() { 
     $scope.loading = true; 
     $scope.error = false; 
     $http.get('http://www.omdbapi.com/?s=' + $scope.search + '&r=json') 
       .then(function (res) { 
        var titles = []; 
        angular.forEach(res.data.Search, function(item){ 
         $http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){ 
         if (res.data.Poster === "N/A") { 
         res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; 
         } 
         titles.push(res.data); 
         }); 
        }); 

        $scope.movie = titles; 
        $scope.results = true; 
        $scope.error = false; 
        $scope.loading = false; 


        if (titles.length==0) {   // not working 
         $scope.results = false; 
         $scope.error = true; 
        } 


       }) 

Я попробовал несколько вещей, как:Как проверить, пуст ли массив объектов или нет?

Object.getOwnPropertyNames(titles).length === 0) 
obj == null 

Ни один из них не похоже на работу ...

+1

любой рабочий образец ??? – Vijay

+0

Можете ли вы отлаживать и проверять, действительно ли длина равна нулю! – Vishwanath

ответ

0

$http.get() является асинхронной, так что оператор if (titles.length==0) { запускается на выполнение сразу.

Имейте счетчик, чтобы определить, когда все обещания будут решены, а затем выполните проверку. Переместите оператор if внутри обратного вызова.

var count = res.data.Search.length; 

angular.forEach(res.data.Search, function(item){ 
    $http.get('http://www.o....rest of code').then(function(res) { 
     // rest of code 

     titles.push(res.data); 
     if (!count-- && !titles.length) { 
      $scope.results = false; 
      $scope.error = true; 
     } 
     } 
    }); 
}); 
+1

Спасибо, он отлично работал! –

2

Это происходит из-за неправильный объем:

var titles = []; определяется внутри .then

и вы проверяете длину за пределами .then

так titles не доступен за пределами .then это не сработало. (undefined.length==0)

Решение:

.then(function (res) { 
        var titles = []; 
        angular.forEach(res.data.Search, function(item){ 
         $http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){ 
         if (res.data.Poster === "N/A") { 
         res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; 
         } 
         titles.push(res.data); 
         }); 
       $scope.movie = titles; 
       $scope.results = true; 
       $scope.error = false; 
       $scope.loading = false; 


       if (titles.length==0) {   // now this will work 
        $scope.results = false; 
        $scope.error = true; 
       } 
    });//titles will not be available after this. 
0

В вашем случае проверка

titles.length 

будет выполняться до

titles.push 

потому что вы используете асинхронный запрос, который вернется позже. Вам нужно обернуть свои заявления в ответный блок запроса.

0

Подобно тому, как в стороне, но полезно для моей практики и вашей будущей помощи:

Части проблемы вы имеющая сферу-менеджмент (JS-Scope, не угловой $ объема), частью была параллелизм -management, и часть его, казалось, была простым старым форматированием области, что затрудняло просмотр, где все блоки управления начинаются и заканчиваются (что становится жалким, когда это не просто if/else, но и с обратными вызовами/обещаниями).

Это небольшой пример того, как вы могли бы рассмотреть решение этих проблем, с помощью быстрых реорганизовать ваши вопросы:

function pluck (key) { 
 
    return function pluckFrom(obj) { return obj[key]; }; 
 
} 
 

 
angular.module("app", ["ui.bootstrap"]); 
 

 
angular.moule("app").service("omdbService", ["$http", function ($http) { 
 
    function getSearch (search) { 
 
    var searching = $http.get("http://www.omdbapi.com/?s=" + search + "&r=json") 
 
     .then(pluck("data")); 
 
    return searching; 
 
    } 
 

 
    function getMovie (title) { 
 
    var searching = $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=full&r=json") 
 
     .then(pluck("data")); 
 
    return searching; 
 
    } 
 

 
    return { 
 
    getSearch: getSearch, 
 
    getMovie: getMovie, 
 
    getPlaceholderPoster: function() { return "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; } 
 
    }; 
 
}]); 
 

 

 

 
angular.moule("app").controller("ListCtrl", ["$scope", "$q", "omdbService", function ($scope, $q, omdb) { 
 
    function loadMovie (movie) { 
 
    return omdb.getMovie(movie.Title)["catch"](function() { return undefined; }); 
 
    } 
 
    function movieExists (movie) { return !!movie; } 
 
    function updatePoster (movie) { 
 
    movie.Poster = movie.Poster || omdb.getPlaceholderPoster(); 
 
    return movie; 
 
    } 
 
    function setResults (movies) { 
 
    $scope.movie = movies; // $scope.movies, instead? 
 
    $scope.results = true; 
 
    $scope.error = false; 
 
    $scope.loading = false; 
 
    } 
 

 
    function handleError() { 
 
    $scope.results = false; 
 
    $scope.error = true; 
 
    } 
 

 
    $scope.submit = function() { 
 
    $scope.loading = true; 
 
    $scope.error = false; 
 

 
    omdb.getSearch($scope.search) 
 
     .then(pluck("Search")) 
 
     .then(function (movies) { return $q.all(movies.map(loadMovie)); }) 
 
     .then(function (movies) { return movies.filter(movieExists).map(updatePoster); }) 
 
     .then(setResults, handleError); 
 
    }; 
 

 
}]);

Есть 8000 действительные способы обработки этого, и весь увидит это немного по-другому.
Это также не совсем так, как я бы справился с этим в процессе производства, но не слишком далеко ...

Перемещение всех конечных точек на службу, которая отвечает за это означает, что любой контроллер в вашей системе (с этим модулем как зависимость) могут получить к ним доступ.

Выполнение небольших действий для каждой функции и использование методов Array.prototype выполняют итерацию (при необходимости IE8 можно открепить) означает, что каждая функция является суперспецифичной.

Обертывая контроллеры/сервисные функции в массивах и называя их зависимости, теперь они дружелюбивы.

Тело submit() составляет менее 10 строк и имеет дело со всеми видами сумасшедших асинхронных материалов, но я знаю, что я обрабатывал ошибки, как один из фильмов, возвращающих 404 (мой код все равно должен срабатывать, оставшиеся фильмы, код других может не отображаться - в большинстве случаев код никогда не приведет к успеху или не завершится полностью через программу, если на сервере возникла ошибка для фильма). Теперь я не проверяю, что сервер отправляет нужные данные для «фильма», но это другое.

+0

Я пробовал свой код так, как есть. Это intialising все в моем коде только в начале, как ошибка notif, loading notif и т. Д. Если вы хотите, я могу опубликовать ссылку репо для вас. –

+0

Я обязательно посмотрю в течение следующих нескольких дней и, возможно, отправлю PR после этого. – Norguard

Смежные вопросы