2015-03-20 11 views
6

मैं एक $ http कॉल पर काम कर रहा हूं जो एकाधिक एपीआई में से प्रत्येक पर लूप करता है और एक ही ऑब्जेक्ट में सभी डेटा देता है। जब आमतौर पर $ http कॉल किया जाता है तो हल करने के लिए मेरे पास वादा तैयार होता है। इस के समान:

function getAllData(api) { 
    return $http({ 
     method: 'GET', 
     url: '/api/' + api 
    }) 
    .then(sendResponseData) 
    .catch (sendGetVolunteerError); 
} 

वर्तमान समारोह मैं एक एपीआई से अधिक छोरों है और एक सरणी में एपीआई में प्रत्येक वस्तु धक्का और फिर एक समग्र सरणी में यह धक्का। मेरे पास यह कामकाज था, एक बहु-आयामी सरणी लौट रहा था, जिसे बाहर निकालना आवश्यक था।

मैं इसे एक वादे में वापस करना चाहता हूं, लेकिन undefined लौटा रहा हूं। यह है, जो कि अभी तक मेरे पास है? क्या इस दृष्टिकोण के लिए कोई बेहतर तरीका है?

dataService:

function getSearchData() { 
    return { 
     loadDataFromUrls: function() { 
      var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"]; 
      var deferred = $q.defer(); 
      var log = []; 
      angular.forEach(apiList, function (item, key) { 
       var logNew = []; 
       $http({ 
        method: 'GET', 
        url: '/api/' + item 
       }).then(function (response) { 
        angular.forEach(response.data, function (item, key) { 
         this.push(item); 
        }, logNew); 
        return logNew; 
       }); 
       this.push(logNew); 
      }, log); 
      $q.all(log).then(

      function (results) { 
       deferred.resolve(
       JSON.stringify(results)) 
      }, 

      function (errors) { 
       deferred.reject(errors); 
      }, 

      function (updates) { 
       deferred.update(updates); 
      }); 
      return deferred.promise; 
     } 
    }; 
}; 

नियंत्रक:

function getSearchData(){ 
    return dataService.getSearchData.loadDataFromUrls; 
} 

$scope.searchData = getSearchData(); 
+1

मुझे यकीन है कि यहाँ क्या हो रहा है 100% नहीं कर रहा हूँ - आप कर रहे हैं रिक्त सरणी ('logNew') को 'लॉग' सरणी में नहीं दबाया जा रहा है, जिसे आप प्रतीक्षा करना चाहते हैं? क्या आपको इसके बजाय '$ http' द्वारा वापस 'वादा' को धक्का नहीं देना चाहिए? –

उत्तर

16

$q.all और एक map समारोह आप यहाँ क्या जरूरत है:

function getSearchData() { 
    return { 
     // returns a promise for an object like: 
     // { abo: resultFromAbo, ser: resultFromSer, ... } 
     loadDataFromUrls: function() { 
      var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"]; 

      return $q.all(apiList.map(function (item) { 
       return $http({ 
        method: 'GET', 
        url: '/api/' + item 
       }); 
      })) 
      .then(function (results) { 
       var resultObj = {}; 
       results.forEach(function (val, i) { 
        resultObj[apiList[i]] = val.data; 
       }); 
       return resultObj;   
      }); 
     } 
    }; 
} 
+0

किसी कारण से मैं नियंत्रक में अपरिभाषित लौट रहा हूं: फ़ंक्शन getSearchData() { डेटा लौटाएं सेवा.getSearchData.loadDataFromUrls; } console.log (getSearchData()); – byrdr

+0

@byrdr ऐसा इसलिए है क्योंकि 'getSearchData' किसी ऑब्जेक्ट को 'loadDataFromUrls' के साथ अपनी गुणों में से एक के रूप में देता है, लेकिन आप' getDearchData' 'की संपत्ति के रूप में' loadDataFromUrls' तक पहुंच रहे हैं। आज़माएं: 'फ़ंक्शन getSearchData() {वापसी डेटाService.getSearchData()। LoadDataFromUrls; } console.log (getSearchData()); 'यह सवाल छोड़ देता है कि आपके डेटा सेवा और आपके' getSearchData' फ़ंक्शन 'के बीच एक अतिरिक्त परत क्यों है। – JLRishe

+0

यह समझ में आता है, धन्यवाद। उपर्युक्त कोड वर्तमान में फ़ंक्शन को लॉग करता है। – byrdr

0

आप $q (अपने कोड में की तरह हल हो गई वादे नहीं) में वादों की एक सूची में जोड़ना चाहिए, जो एक $promise service

उदाहरण है :

var firstPromise = service1.getMethod1().$promise; 
var secondPromise = service2.getMethod2().$promise; 
$q.all([firstPromise, secondPromise]).then(function(dataList){ 
    // dataList[0] will be result of `firstPromise` 
    // dataList[1] will be result of `secondPromise` 
}); 
1

मैं कुछ इस तरह करना होगा आप API कॉल की एक मनमाना सेट किया हुआ है:

function getSearchData(){ 
    var deferred = $q.defer(); 
    var noOfCalls = apiList.length; 
    var results = []; 
    var called = 0; 

    angular.forEach(apiList, function(item, key) { 
     $http.get(url).then(function(result){ 
      results.push(result); 
      called++; 
      if(called == noOfCalls){ 
       deferred.resolve(results); 
      }  
     }) 
    }); 

    return deferred.promise; 
} 

लेकिन अगर आप जानते हैं कि प्रत्येक API कॉल इस तरह

function search1(){ 
     return $http.get(search1Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search2(){ 
     return $http.get(search2Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search3(){ 
     return $http.get(search3Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search4(){ 
     return $http.get(search4Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function getSearchResult(){ 

    return $q.all([search1(), search2(), search3(), search4()]).then(function(results){ 
     // OPTIONAL aggregate results before resolving 
     return results; 
    }); 
} 
में $ सब के सब उपयोग करने के लिए अपने बेहतर प्रतिनिधित्व
+0

क्या आपका मतलब '$ q.defer()' था? – GregL

+0

[स्थगित एंटीपार्टर्न क्या है और मैं इससे कैसे बचूं?] (Http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it) – JLRishe

+0

हाँ .. मेरी गलती को देखने के लिए धन्यवाद :) –

संबंधित मुद्दे