2015-08-14 2 views
0

У меня есть сервис под название serviceCallJson, который получает данные из файла JSON, и у меня есть еще один сервис validateIn, который проверяет входные данные от пользователя на основе данных, присутствующих в формате JSON.AngularJS службы возвращения неопределенные

(function() { 
    "use strict"; 

    var serviceCallJson = function($http) { 
     this.getCustomers = function() { 
     var promise = $http({ 
      method : 'get', 
      url : '../viewersData/userPwdPair.json' 
      }) 

     .success(function(data) { 
      return data; 
      }); 
    } 
    } 

    var validateIn = function (serviceCallJson) { 
     this.called = function(username, password) { 
      this.returnedData = serviceCallJson.getCustomers(); 
      console.log(this.returnedData); //undefined 
      var i = 0; 

      angular.forEach(this.returnedData, function(value, key){ 
       while (i < 10) { 
       if(value[i].username == username) { 
        if(value[i].password == password) { 
        alert("Logged In"); 
        } 
       } 

       i = i + 1; 
       } 
      }); 
     } 

    } 

    angular.module('assignment1App') 
     .service ('serviceCallJson', serviceCallJson) 

    angular.module('assignment1App') 
    .service ('validateIn', ['serviceCallJson', validateIn]) 

}()) 

У меня есть следующие вопросы:

1) Я не понимаю, почему returnedData' iswhen I am returning the data fetched by the неопределенную serviceCallJson service on success`?

2) Когда я console.trace() в console, я получаю следующий результат:

enter image description here

Почему я не в состоянии увидеть трассировки стека? (Я ожидал увидеть мои функции контроллера вызывается, но он возвращает анонимную функцию)

Решение первого вопроса

Спасибо за все ваши комментарии. Они очень помогли в отладке моего приложения. Следующий код заставил его работать. Я все еще не могу понять второй вопрос.

serviceCallJson сервис

(function() { 
    "use strict"; 

    var serviceCallJson = function($http) { 
     this.getCustomers = function() { 
     return $http({ 
      method : 'get', 
      url : '../viewersData/userPwdPair.json' 
      }); 
     }; 
    }; 

    angular.module('assignment1App') 
    .service ('serviceCallJson', serviceCallJson); 
}()); 

validateIn обслуживание:

(function() { 
    "use strict"; 

    var validateIn = function (serviceCallJson) { 
     this.called = function(username, password) { 

      serviceCallJson.getCustomers() 
       .then(function (returnedData) { 
       var i = 0; 
       var j = 0; 

       angular.forEach(returnedData.data, function(value){ 
        while (i < 10) { 
        if(value[i].username == username) { 
         if(value[i].password == password) { 
         console.log("Logged In"); 
         j = j + 1; 
         } 
        } 
        i = i + 1; 
        } 

        if (j === 0) { 
        console.log("Username or password is wrong"); 
        } 
       }); 
       }); 
     }; 

    }; 
     angular.module('assignment1App') 
     .service ('validateIn', ['serviceCallJson', validateIn]); 
}()); 

Update - Второй вопрос

Console.trace() заносились анонимную функцию вместо имен методов, которые в настоящее время называются потому, что я вызывал его самостоятельно в консоли. Следующее использование console.trace() в моей службе validate дает правильную трассировку стека со всеми именами функций и вызываемыми свойствами.

(function() { 
    "use strict"; 

    var validate = function (fetchDataService) { 
     this.verify = function(username, password) { 
      console.trace(); 

      fetchDataService.getCustomers() 
       .then(function (returnedData) { 
       var i = 0; 
       var count = 0; 

       angular.forEach(returnedData.data, function(value){ 
        while (i < 10) { 
        if(value[i].username == username) { 
         if(value[i].password == password) { 
         console.log("Logged In"); 
         count = count + 1; 
         } 
        } 
        i = i + 1; 
        } 

        if (count === 0) { 
        console.log("Username or password is wrong"); 
        } 
       }); 
       }); 
     }; 

    }; 
     angular.module('assignment1App') 
     .service ('validate', ['fetchDataService', validate]); 
}()); 
+0

это выглядит, как вы определили обещание, но никогда не запускал его. 'var agree = $ http ...' не собирается на самом деле делать вызов сервера. Кроме того, возврат собирается присвоить 'data'' prom'; 'getCustomers' все еще ничего не возвращает. – Claies

+0

Возвращение с асинхронным вызовом почти всегда будет неопределенным, вам нужно настроить функции обратного вызова –

+1

и возврат из внутренней функции не возвращается к внешнему. return to success callback ничего не сделает – charlietfl

ответ

0

Так вот лучшее объяснение: Когда вы делаете $http вызов, вы делаете вызов функции асинхронной. Функции Async завершаются в будущем. Поэтому необходимо учитывать следующее:

var res = myAsyncFunction(..); // Let's say $http call takes 5 seconds. 

// Execution is linear in JS, so $http cannot actually return 
// a "result" at this point. 

console.log(res); //res is not the result we are expecting. 

Перед JS были обещания, там было что-то называется обратного вызова ад:

asyncFn(..., function(res) { 
    anotherAsyncFn(res, function(res2) { 
    ... ({ 
     ... ({ 
     // After a bunch of async calls, lets print the final result: 
     console.log(res24); 
     }); 
    }); 
    }); 
}); 

Теперь есть обещания:

asyncFn(...) 
    .then(anotherAsyncFn) 
    .then(...) 
    .then(...) 
    ... 
    .then(function(res) { 
    console.log(res); 
    }); 

Так что в вашем случае:

1) $http звонок возвращает обещание. 2) Вы возвращаете это обещание из сервисной функции. 3) Используя promise.then, вы назначаете обратный вызов для вызова по завершении обещания.

Для вашего второго вопроса: Какой бы язык вы ни использовали, если есть синтаксический сахар для асинхронных функций, трассировка стека будет сложнее для них, хотя код выглядит очень просто. Вы можете видеть, что это происходит в C# async/await, JS обещает/генерирует/async-wait и т. Д. И, возможно, Go подпрограммы.


var serviceCallJson = function($http) { 
    this.getCustomers = function() { 
    // Return the promise 
    return $http({ 
     method : 'get', 
     url : '../viewersData/userPwdPair.json' 
     }) 
    .success(function(data) { 
     return data; 
     }); 
    } 
} 

// In controller: 
// Promise is returned. So you can use 'then' 
// Learn how to use promises. You can check out kriskowal/q 
serviceCallJson.getCustomers().then(function (data) { 
    //do something with data 
    $scope.myData = data; 
}); 
+1

внутри 'then' будет быть 'data.data' ... возвращение от успеха бесполезно и не является частью цепочки обещаний – charlietfl

+0

, он может понять, что он сам, если он в нее. – mostruash

+0

Это глупый комментарий. Вы предоставили код-ответ, и он должен по крайней мере работать – charlietfl

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