Question

I set up a method to be called by an ng-click event in my html:

<div ng-repeat="section in model.sections">
    <a ng-click="updateSection($index)">
</div>

Then in my javascript file, I had the following service:

.factory('Sections', function($resource){
    return{
        onUnits: $resource('/api/sections/:uuid/units', {uuid:'@sectionUUID'}, {
            get: {method: 'GET', params:{uuid: '@uuid'}, isArray:true}
        }
    }
}

The method being called from the html is:

$scope.updateSection = function(index){
    $scope.model.sections[index].sectionUnits = Sections.onUnits.get({uuid: $scope.model.sections[index].sectionUUID}
        ,console.log($scope.model.sections[index])
        );
    }

before this update happens,

$scope.model.sections[0].sectionUnits == ['d1','d2']

which is the list of id's of units associated with this section. This method basically updates this list with the real unit objects that looks like:

.sectionUnits = [{unitUUID: 'd1',
                  materials: ['m1','m2','m3']
                  }, {... }]

in my browser, the code above returns the updated section object that I was looking for, with all the unit objects nested under the section.

However, what I really wanted, was to implement a callback that takes the list of id's of all the materials associated with the unit in this updated section object, and retrieve them.

If I try that, and have the following call back instead, I get the list of sectionUnits that's still just the id's:

$scope.updateSection = function(index){
    $scope.model.sections[index].sectionUnits = Sections.onUnits.get({uuid: $scope.model.sections[index].sectionUUID}
        ,console.log($scope.model.sections[index].sectionUnits)
        );
    }

I have looked through a lot of SO threads and the original doc, but am kind of stuck at this point.

Thanks!

Was it helpful?

Solution

The pattern that I have encountered the most is to create a resource object, then make assignments in the callback. So instead of your current updateSections function, you would have:

$scope.updateSection = function(index) {
    Sections.onUnits.get(
        {uuid: $scope.model.sections[index].sectionUUID},
        function(results) {$scope.model.sections[index].sectionUnits = results}
    )
}

I think that in your code the results of the GET don't actually get assigned, which is why you're getting back the original array of ids.

Note that the assignment only occurs on successful GET of the resource. You should have a separate callback to handle any errors.

Also remember that services are singletons, so if you're passing it around, be careful to not change Sections, or it'll change everywhere else around.

If you wanted to chain requests such that after retrieving a section, you get the materials, then you would do that in your callback, right after the assignment.:

$scope.updateSection = function(index) {
    Sections.onUnits.get(
        {uuid: $scope.model.sections[index].sectionUUID},
        function(results) {
            $scope.model.sections[index].sectionUnits = results;
            // Should contain some looping mechanism since results is an array.
            $scope.getMaterials(results);
        }
    )
}

A couple of other notes on your code:

  • Something seems wrong about your initial method call to get the resource. At that point, you say that the sectionUnits object is an array of strings, but your updateSection() method call tries to reference the array as an object. You say that you can get a console printout, so I'm guessing that it works, but you just made a typo
  • It seems like a bad idea to mutate the sectionUnits object from an array of strings to an array objects. Maybe initialize it as .sectionUnits = [{unitUUID:'d1'}, {unitUUID:'d2'}]?
  • You may want to take a look at Restangular, which basically wraps $resource to be a bit more user friendly. I've found it to be really easy to work with.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top