angularchobo angularchobo - 3 months ago 29
Javascript Question

Callback from Angularjs factory

I want to get a callback from a factory. If I understand correctly, the callback should be in the deepest nested function (i.e. under

var myResult = $filter('filter')(myData, {id:exnum})[0];
, but I get "TypeError: callback is not a function".

My factory calls another factory, gets a value and injects it into a third one for the final result. This final result logs correctly to console, but I cannot callback to the controller.

Any feedback would be appreciated.

angular.module('resourceFetch', [])
.factory('ResourceFetch', ['JsonService', 'UserProgress', '$filter', function(JsonService, UserProgress, $filter) {

var resourceResult = {};
resourceResult.getResource = function(callback){

UserProgress.getProgress(function(exnum, callback) {
JsonService.get(function(data){
var myData = [];
var myData = data.exercises;
var myResult = [];
var myResult = $filter('filter')(myData, {id:exnum})[0];
console.log(myResult) // <- this displays correctly
callback(myResult); // <- "TypeError: callback is not a function"
});
});
//callback(myResult); <- here "myResult is not defined"
};
return resourceResult;
}]);


This is the controller:

myApp.controller('ResourceFetchTest', function($scope, ResourceFetch) {

$scope.myresults = ResourceFetch.getResource(function(obj1){
console.log('obj1 is ' + obj1);
$scope.MyData = obj1;
$scope.MySelectedData = obj1.string1;
});
});

Answer

You could use a promise to return the object

Something like:

angular.module('resourceFetch', [])
.factory('ResourceFetch', ['JsonService', 'UserProgress', '$filter','$q', function(JsonService, UserProgress, $filter,$q) {

    var resourceResult = {};
    resourceResult.getResource = function(){
    var defer = $q.defer();
      UserProgress.getProgress(function(exnum) {
        JsonService.get(function(data){
        var myData = [];
        var myData = data.exercises;
        var myResult = [];
        var myResult = $filter('filter')(myData, {id:exnum})[0];
        console.log(myResult) // <- this displays correctly
        defer.resolve(myResult); 
        });
     });
   return defer.promise;
   };
    return resourceResult;
}]);

and in the controller:

myApp.controller('ResourceFetchTest', function($scope, ResourceFetch) {

    $scope.myresults = ResourceFetch.getResource().then(function(obj1){
       console.log('obj1 is ' + obj1);
       $scope.MyData = obj1;
       $scope.MySelectedData = obj1.string1;
    }); 
});

here's the documentation on promises:https://docs.angularjs.org/api/ng/service/$q

Let me know if you have questions I had the simular problem today and fixed it this way