2014-09-19 3 views
2

Я пытаюсь написать фабрику, которая получает данные из двух источников и использует один источник для расширения данных в другом объекте.

app.factory('information', ['$http', '$q', 'players', 'matches', function($http, $q, players, matches) { 
    return { 
     // Returns all matches and players including extra parsing 
     get: function() { 
      return players.get().success(function(data) { 
       players = data; 

       matches.get().success(function(data) { 
        matches = data; 

        for (match in matches) { 
         matches[match].a_player1 = players.filter(function(player) { return player.username == matches[match].a_player1 })[0]; 
         matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0]; 
         matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0]; 
         matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0]; 
         console.log(matches) 
        } 

        return matches; 
       }); 
      }); 
     }, 
    } 
}]); 

Оба matches.get() и players.get() простые GET запросы к API, как так:

app.factory('players', function($http) { 
    return { 
     get: function() { 
      return $http({ 
       method: 'GET', 
       url: '/players', 
      }); 
     }, 
    } 
}); 

Но приведенный выше код (конечно) возвращает players объект, а я хочу, чтобы вернуть matches объект после он объединяется с объектом players.

Любые советы о том, как это сделать?

ответ

5

Эта функция ничего не вернет, поскольку вы не можете напрямую вернуть значение из операции async, либо вернуть обещание, либо использовать обратный вызов. Но я думаю, что вы ищете является $q.all:

return { 
     // Returns all matches and players including extra parsing 
     getEverything: function() { 

     var getPlayers= $http({ 
      method: 'GET', 
      url: '/players', 
     }); 
     var getMatches= $http({ 
      method: 'GET', 
      url: '/matches', 
     }); 

      return $q.all([getPlayers,getMatches]); 
     } 
} 

Использование:

getEverything().then(function(data){ 
    var players=data[0].data; 
    var matches=data[1].data; 
}) 

EDIT:

Ненужные, но переместить это назад на заводе:

getEverything: function() { 
      var getPlayers= $http({ 
       method: 'GET', 
       url: '/players', 
      }); 
      var getMatches= $http({ 
       method: 'GET', 
       url: '/matches', 
      }); 
      return $q.all([getPlayers,getMatches]); 
}, 
getEverythingMapped:function(){ 
var deferred = $q.defer(); 
this.getEverything().then(function(data){ 
     var players=data[0].data; 
     var matches=data[1].data; 
//do as many loops on either result set as you like 
       for (match in matches) { 
        matches[match].a_player1 = players.filter(function(player) { return player.username == matches[match].a_player1 })[0]; 
        matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0]; 
        matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0]; 
        matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0]; 
        console.log(matches) 
//use of a promise here allows us top use this method using -then, we need to so this since we're 
//waiting for the result of an async server call before we can loop through players and matches 
        deferred.resolve(matches); 
       } 


} 
} 

Теперь вы должны использовать вышеуказанный метод, как это в вашем контроллере:

information.getEverythingMapped().then(function(matches){ 
console.log(matches); 
}) 
+0

Но где бы я анализирую свои данные (цикл 'for in')? –

+0

Везде. То, что я написал, является просто планом, вы можете поместить цикл for после вызова службы после того, как 'var matches = data [1] .data;' –

+0

В этом конкретном примере, поскольку нет зависимости от двух вызовов GET, $ q это лучший вариант. Вложенные $ http, когда у вас есть зависимости. – ABOS

2

В соответствии с документами для $http эта услуга возвращает обещание. Поэтому нет необходимости в $ д службу в этом случае она может быть просто написана так:

app.factory('information', ['$http', 'players', 'matches', function($http, players, matches) { 
    return { 
     // Returns all matches and players including extra parsing 
     get: function(callback) { 
      players.get().then(function(playersData) { 
       matches.get().then(function(matchesData) { 
        matches = matchesData; 
        players = playersData; 
        for (match in matches) { 
         matches[match].a_player1 = players.filter(function(player) { return player.username == matches[match].a_player1 })[0]; 
         matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0]; 
         matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0]; 
         matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0]; 
         console.log(matches) 
        } 
        callback(matches); 
       }); 
      }); 
     }, 
    } 
}]); 

и в информации о вызове контроллера, как это:

information.get(function(data){ 
    console.log(data); 
}); 
+0

Я пробовал это уже, но он продолжает возвращать 'TypeError: undefined не является функцией' –

+0

Ошибка, может быть, в чем-то еще, вы положили консоли для матчей и игроков и проверили значения? – V31

+0

Это определенно функция get, и я думаю, что это происходит, потому что она ничего не возвращает. Я не могу назвать его как 'information.get(). Succes (function() {...}) 'либо, потому что он не возвращает обещание. И вызов 'console.log (information.get())' возвращает undefined, что соответствует моей гипотезе. –