2017-09-15 93 views
2

我有一个物品数组,我将从localStorage获得。在AngularJS中有条件地创建一个承诺

    var items = JSON.parse($window.localStorage.selectedResources)['server']; 

        var arr = []; 

        var idsArray = []; 

        angular.forEach(items, function (item) { 
         idsArray.push(item.id); 
        }); 

然后我火API调用...

    //Make the API call 
        ds.getBillInfo(idsArray) 
         .then(function(response){ 
          var serversList = []; 
          for (var key in response) { 
           // iterate over response 

的问题是,如果项目数组是空的,所以做了idsArray。 然后错误说Cannot read property 'then' of undefined

我想要做的是even if the idsArray is empty , I want lines to execute inside the then block thinking as there is no promise

我该怎么做?

编辑

如果我做$q.all([ds.getBillInfo(idsArray)])那么就没有错误。

getBillInfo()样子:

 this.getBillInfo = function(idsArray){ 
      if(!idsArray.length) return; 
      var segmentUrl = ''; 
      for(var i =0;i<idsArray.length;i++){ 
       if(i != (idsArray.length-1)) 
        segmentUrl += 'ids='+idsArray[i]+'&'; 
       else 
        segmentUrl += 'ids='+idsArray[i]; 
      } 
      return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'}); 
     }; 
+1

您需要修改'getBillInfo'总是返回一个承诺 – SLaks

+0

东西是不正确这里...喜欢@SLaks说。 – Pytth

+0

...即使返回类似'Promise.reject('empty')'的东西也会工作,并且最终会在catch或Promise.resolve()中解析 – adeneo

回答

2

getBillInfo包装你的逻辑和新的承诺和空阵列上解决这个问题。

是这样的:

self.getBillInfo = function(array){ 

    var deferred = $q.defer(); 

    if(array.length == 0){ 
    deferred.resolve([]); // return empty list 
    } 
    else{ 
    var segmentUrl = ''; 
    for(var i =0;i<idsArray.length;i++){ 
     if(i != (idsArray.length-1)) 
      segmentUrl += 'ids='+idsArray[i]+'&'; 
     else 
      segmentUrl += 'ids='+idsArray[i]; 
     } 
     HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'}) 
     .then(function (response) { 
       deferred.resolve(response.data); 
     } 
     , function (error) { 
       deferred.reject(error); 
     }); 

    } 

    return deferred.promise; 
} 

[编辑]

问候@JC Ford点,由于HttpWrapper返回答应我们可以写上面的逻辑与不同的方式为:

self.getBillInfo = function(array){ 

    if(array.length == 0){ 
    return $q.resolve([]); // return empty list; 
    } 
    else{ 
    var segmentUrl = ''; 
    for(var i =0;i<idsArray.length;i++){ 
     if(i != (idsArray.length-1)) 
      segmentUrl += 'ids='+idsArray[i]+'&'; 
     else 
      segmentUrl += 'ids='+idsArray[i]; 
     } 
     return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'});   
    } 
} 
+0

如果'HttpWrapper.send'已经返回一个promise,这是多余的。它会起作用,但是使用'$ q.defer()'实际上是为了在你还没有的时候创造一个承诺。这过于复杂,因此不是最佳实践。 –

+0

@JCFord同意,但它看起来很清楚,无论如何我会用你的方式更新答案;) –

+0

使用'$ q.resolve([])'而不是延迟。 – SLaks

1

注入$ q服务,以便在getBillInfo()中可访问。然后,您可以将值包含在$q.resolve()中以作出返回该值的承诺。 (这个值甚至可能是另一个承诺。)因此,如果你的getBillInfo()函数有时需要提前返回而没有值,那么只需返回一个空的$q.resolve(),以确保你总是返回一个承诺。

this.getBillInfo = function(idsArray){ 

    //This returns undefined and causes your error. 
    if(!idsArray.length) return; 

    //This returns a promise that resolves immediately and executes your .then() handler. 
    if(!idsArray.length) return $q.resolve(); 

    //This returns a promise that rejects immediately and executes your .catch() handler 
    if(!idsArray.length) return $q.reject(); 

    var segmentUrl = ''; 
    for(var i =0;i<idsArray.length;i++){ 
     if(i != (idsArray.length-1)) 
      segmentUrl += 'ids='+idsArray[i]+'&'; 
     else 
      segmentUrl += 'ids='+idsArray[i]; 
    } 
    return HttpWrapper.send('/api/bill?bill=t&'+segmentUrl, {"operation": 'GET'}); 
}; 
+0

注意你有'if(!idsArray.length)return'的地方。而是返回$ q.resolve()。 –