1

I have service which gets data from server and sends it to controller:

Service:

publicApp.angularModule.factory('resultService', function ($http) {
        return {
            getResult: function() {
                return $http.get("/Result/GetResult")
                    .success(function(result) {
                        return result.data;
                    }).error(function(result) {
                        console.log("error" + result);
                    });
            },
        };
    });

Controller:

publicApp.angularModule.controller('PublicResultCtrl', function ($scope, $location, resultService) {

    resultService.getResult().then(function (resultResponse) {
        $scope.data = resultResponse.data;
        $scope.graph = [];

        _.forEach($scope.data.TreningExerciseScores, function(item) {
            $scope.graph.push(addDataToGraph(item.Item2, item.Item1));
        });

    });

    var addDataToGraph = function (num, text) {
        return {
            y: num,
            legendText: text,
        };
    };

});

And I have directive which should get data from controller. I call directive like this:

<div id="graph" style="width: 200px; height: 200px" canvasjs graphData="graph"></div> 

And here is my directive:

publicApp.angularModule.directive('canvasjs', function () {


    return {
        restrict: 'A',
        scope: {data : '=graphData'} ,
        link: function (scope, element, attrs) {

            scope.$watch('data', function (data) {
                    console.log(scope.data);

            });         
        }
    };
});

But scope.data is undefined. I know that $http.get is async operation but shouldn't scope.$watch get updates ?

3 Answers 3

2

Try to pass value to directive as: canvasjs="graph".

In my example I simulate response from service and return promise.

HTML

<div ng-controller="fessCntrl">
    <div id="graph" style="width: 200px; height: 200px" canvasjs="graph"></div>
    <pre>   graph:  {{graph|json}}  </pre>
    <pre>   data:  {{data|json}}  </pre>  
</div>

JS

var fessmodule = angular.module('myModule', ['ngResource']);

fessmodule.controller('fessCntrl', function ($scope, resultService) {

    resultService.getResult().then(function (resultResponse) {
        console.log(resultResponse);

        $scope.data = resultResponse.data;
        $scope.graph = [];

        angular.forEach($scope.data.TreningExerciseScores, function (item, key) {
            $scope.graph.push(addDataToGraph(item.Item2, item.Item1));
        });


    });

    var addDataToGraph = function (num, text) {
        return {
            y: num,
            legendText: text,
        };
    };

});

fessmodule.$inject = ['$scope', 'Data'];

fessmodule.directive('canvasjs', function () {
    return {
        restrict: 'A',

        link: function (scope, element, attrs) {

            scope.$watch('data', function (data) {
                console.log("fff", scope.data);

            });
        }
    };
});

fessmodule.factory('resultService', ['$resource', '$q', function ($resource, $q) {
    var input = {
        data: {
            TreningExerciseScores: [{
                Item1: "aaa"
            },
            {
                Item2: "bbb"
            }]
        }
    };

    var factory = {
        getResult: function (selectedSubject) {
            var deferred = $q.defer();

            deferred.resolve(input);

            return deferred.promise;
        }

    }
    return factory;
}]);

Demo Fiddle

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

1 Comment

@hyperN see my answer and Demo.
2

If you are going to handle the promise in your controller:

resultService.getResult().then(function (resultResponse) {
        $scope.data = resultResponse.data;
        $scope.graph = [];

        _.forEach($scope.data.TreningExerciseScores, function(item) {
            $scope.graph.push(addDataToGraph(item.Item2, item.Item1));
        });

    });

There is no need to handle it in your service:

getResult: function() {
                return $http.get("/Result/GetResult");
            },

If you want to handle only the error in the service then you need to wrap in a promise again. You can use $q.when for this:

getResult: function() {
                return $http.get("/Result/GetResult")
                    .success(function(result) {
                        return $q.when(result.data);
                    }).error(function(result) {
                        // not sure what you want to do here
                        console.log("error" + result);
                        return $q.when(result);

                    });
            },

$q.when will wrap a promise around the object if it is not already a promise.

6 Comments

Thanks for the suggestions, I've changed my code according to them, but still scope.data is undefined
Maybe you need to return $q.when(result) and not result.data. Otherwise, you are doing a result.data.data.
I've logged $scope.graph and everything was fine there so it's not problem with my service, I believe problem is in directive
Where are you logging? Try logging result in your resultService and your controller. See if you can see the data property on both.
You were right result.data in resultService was undefined, and result was object, and in controller was everything ok
|
0

You can't return the data in a success() handler and expect it to make it back. You have to chain another promise (return defer.promise()), or do the success in your controller and modify the $scope in your result. Or just return the whole $http call which is already a promise.

Comments

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.