One thing that can make your life a little bit easier is the $q.all
function - it accepts an array of promises and resolves into an array of
resolved values, as long as the promises all resolve (and it will activate
error resolution if any of the promises error out). I'm pretty sure that
the nested forEach thenable stuff will miss errors if the voters call
errors out, but I'm not 100% sure of that. I also tend to use $http over
$resource personally, so this may not be right either.

$q.all(scores.map(function(score) {
  return score.getList('voters') //assuming getList returns a promise for
the list
})).then(function (votersArray) {
  //do something with the votersArray like put votersArray[i] on
$scope.votes[i].voters for all values of i.
  return $q.all(scores.map(function(score) {
    return score.getList("witnesses")
  })).then(function (witnessArray) {
     //more here
}).catch(function (error) {
  //process error
})

But yeah, there's a lot of $http calls there, which is annoying. It's just
ugly at times, and if you have multiple controllers and pages with the same
kinds of data models, you'll be Repeating Yourself.

Personally, I had to deal with a general-case problem of having side-loaded
lists of models attached to other models (Users have Posts, Communities
have Users, etc). I ended up using Object.defineProperty to make a property
like User.posts, where in the getter function it looks like:

get: function() {
  //check to see if this._cache.promise exists, if not, set it equal to
$http.get('appropriate url')
// this._cache.promise.then (val)=> this._cache.values = val
// this._cache.values ?= []
// return this._cache.values
}

It's not the simplest solution on the back end, but on the front end, you
can just put a User object on the scope and then have user.posts do what
you expect it to do without needing to worry about manually resolving
side-loaded promises. If an object's side-loaded list doesn't get touched
by angular, it doesn't load, and if it does, the first time through it'll
look like an empty list, but as soon as the $http promise resolves angular
takes care of the rest. If you really need to wait on the call, you can
manually grab the promise out of the cache and then it. It more or less
covers for the way angular used to do promise unwrapping in views, but
without getting hung up in edge cases.

e



On Sat, May 24, 2014 at 10:42 AM, Joberto Diniz <
[email protected]> wrote:

> Hi, I'm using Restangular.
> I need to build a model which is built from 3 calls to the api, how can I
> do that?
> To get my model ready to show, I need to call the following urls:
>
> api/scores/{id}
> api/scores/{id}/voters
> api/scores/{id}/witnesses
>
> Also, when I call api/scores it return all the scores, and then for each
> one, I need to call /voters and /witnesses.
>
> I thought of creating a javascript class ScoreModel which would have all
> the score properties along with the voters and witnesses, then bind the
> ScoreModel array to $scope. But how to coordinate the Restangular calls to
> build the model?
>
> I drafted something, but it's just plain ugly!
>
> scoreApp.factory('Scores', ['Restangular', function (Restangular) {
>     return Restangular.service('scores');
> }]);
>
> var promise = Scores.getList({ timeUp: false });
>     $scope.promise = promise;
>     promise.then(function (scores) {
>         //$scope.scores = scores;
>         var promises = [];
>         scores.forEach(function (score) {
>             promises.push(score.getList('voters'));
>         });
>         $scope.promise = promises;
>         promises.forEach(function (promise) {
>             promise.then(function (voters) {
>
>             });
>         });
>     }, function (data) {
>         toaster.pop('error', '', 'Sorry, but an error occured');
>     });
>
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/angular.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to