3
\$\begingroup\$

Title pretty much says it. I need a way to elegantly handle multiple $resource calls in AngularJS. Right now, I just calling each other call on the success function and calling a callback function to spit the data out when it's down.

Here's what I have so far.

// DataService.js
var resource = $resource('/app/data/event/:id/:ext', {id:'@id',ext:'@ext'}, {"getAll": {method: "GET", isArray: false}});
getAllEvents: function (successcb) {
    var combinedJSON = "[";
    // First Call
    var firstFile = resource.get({ id: 1, ext: '.json' });
    firstFile.$promise.then(function (data) {
        combinedJSON += JSON.stringify(data) + ",";
        // Second Call
        var secondFile = resource.get({ id: 2, ext: '.json' });
        secondFile.$promise.then(function (data) {
            combinedJSON += JSON.stringify(data) + ",";
            // Third Call
            var thirdFile = resource.get({ id: 3, ext: '.json' });
            thirdFile.$promise.then(function (data) {
                combinedJSON += JSON.stringify(data) + ",";
                // Fourth Call
                var fourthFile = resource.get({ id: 4, ext: '.json' });
                fourthFile.$promise.then(function (data) {
                    combinedJSON += JSON.stringify(data) + "]";
                    successcb(combinedJSON); // This is the success call back
                }, function (data) {
                    console.log(data);
                });
            }, function (data) {
                console.log(data);
            });
        }, function (data) {
            console.log(data);
        });
    }, function (data) {
        console.log(data);
    });
}

My callback function just spits out the data

// Controller.js
eventData.getAllEvents(function successcb(events) {
    $scope.foo = events;
});

Is there a better way to handle these types of situations?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Never, and I mean NEVER, manually construct JSON. That's just asking for trouble. Construct the object then use JSON.stringify. FYI, arrays are valid JSON so you can construct an array and pass it to JSON.stringify.

Next, it doesn't seem like your calls depend on each other. You can just launch them all in parallel and use Promise.all (or Angular's equivalent API) listen to know when all of them have resolved. The resolved value is an array of values in the same order as the promises. That guarantees that the first call's result is the first item in the resolved value.

Lastly, since you're already using promises, just return a promise from your function. Using callbacks in the presence of a promise defeats the entire purpose of promises.

One more thing, just pointing out that you are returning JSON, a string, from getAllEvents and not an object. Not sure why you're doing that exactly, but if you aim to get the object for manipulation, you can skip that part.

const resource = $resource('/app/data/event/:id/:ext', {id:'@id',ext:'@ext'}, {"getAll": {method: "GET", isArray: false}})

getAllEvents(){
  const promise1 = resource.get({ id: 1, ext: '.json' }).$promise
  const promise2 = resource.get({ id: 2, ext: '.json' }).$promise
  const promise3 = resource.get({ id: 3, ext: '.json' }).$promise
  const promise4 = resource.get({ id: 4, ext: '.json' }).$promise

  return $q.all([ promise1, promise2, promise3, promise4 ])
}

// Usage
someService.getAllEvents().then(values => {
  // values[0] = your first file
  // values[1] = your second file
  // values[2] = your third file
  // values[3] = your fourth file
});
\$\endgroup\$
2
  • \$\begingroup\$ Well the goal that I was trying to do was to combine the JSON files together. Hence the calls within each other, as well as adding an [ and ] at the beginning/end of the file. Also I was adding a , in between each file. So essentially I wanted to return an array of the JSON values. \$\endgroup\$
    – Jimenemex
    Aug 25, 2017 at 16:56
  • \$\begingroup\$ You should still be able to call successcb() and pass values to it... \$\endgroup\$ Aug 25, 2017 at 17:16

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.