1

I imagine that a solution is going to involve some form of promises although I'm struggling to get my head around how I would implement promises in this scenario.

Essentially I have a service which returns $resource, I then use .query() in the controller to get the array of site contexts. The query callback function then passes the response to a $scope function ($scope.getTaskLists).

The getTaskLists function loops through the site contexts using angular.forEach(). For every loop iteration it will use $http to return any task lists within each site context. Using the .success() promise, each $http request calls another for each loop, this time looping through the $http response (task lists). For each task list, another $http request is called which gets the root folder as we need a parameter later on. The .success() promise for this $http call extracts the parameter and then calls $scope.getTaskItems, passing in various parameters including site context and list id.

The getTaskItems function then uses the above parameters to make an $http request to the list, which will return all the list items. The .success() callback here then loops through all the items and pushes the objects to the task scope.

Ultimately the structure resembles something along these lines:

- $resource.query() // get site contexts
  - angular.forEach(sites)
    - $http().success(... // get task lists
      - angular.forEach(taskLists)
        - $http().success(... // get root context
          - $http().success(... // get task items
            - angular.forEach(taskItems)
              - $scope.tasks.push(taskItem) // push task item to $scope

What I need to do is run some code once all task items have been pushed to $scope.tasks. Is this possible using promises and is there a better way of streamlining the above code so that it isn't mangled spaghetti code consisting of ajax requests and loops?

Thanks

2
  • 1
    this article may be of help: callbackhell.com Commented May 19, 2015 at 15:01
  • So, there are N taskItems in M taskLists in K sites, and you want to create a flat lists of tasks? Commented May 19, 2015 at 18:31

2 Answers 2

0

In my opinion your angular workflow is good. The main problem may be on the server side.

If you need ALL your nested resources. Juste expose it in your json.

In your case you have something like :

[
 {"id":"1", "name":"siteContext1"},
 {"id":"2", "name":"siteContext2"}
]

And probably this kind of structure for all your resources. But in your specific case your first call should meet all you needs instead of giving you only a few information about the resource.

You probably need something like this :

[
 {
  "id":"1",
  "tasks":[{
     "id":"1",
     "rootContext": [{...}]
   }],
  "name":"siteContext1",
 },
{
  "id":"2",
  "tasks":[{
     "id":"2",
     "rootContext": [{...}]
   }],
  "name":"siteContext2",
 }
]

If you can't modify your API. Then you're actually doing it in a good way according to your API ... in my humble opinion.

Actually $http calls return promises. success() is a function fired when the promise is resolved.

Hope it helped you.

Sign up to request clarification or add additional context in comments.

Comments

0

can't you change the back end called by this:

$resource.query() // get site contexts

to get you all the:

$http().success(... // get task items

you need ?

Otherwise it seems to me to be a classical flow/usecase of the promises.

4 Comments

Unfortunately not, I'm using Microsoft SharePoint's REST API so I can't change any of the back end code.
so yep, seems to me it's the correct way to handle many asynchronous requests in angular.
In which case what is the best way of firing an event/function after all the task items have been retrieved? I'm not sure how to write a promise which says once all visits have completed their chain of actions, do x.
So you didn't write the code yet? take a look at this fiddle: jsfiddle.net/Morgorth/uwauLrd4 it's an example of what I did: I use deferred.resolve() with deferred = $q.defer() to send the call back to its parent and it works quite "easily"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.