0

I'm blocked on this problem since a couple of hours, so any help is much appreciated.

i've a controller, in which i defined a variable (an empty array):

function MainCtrl(scope, graph) {
    scope.myVar = [];   
    graph.send("a", "b");
}
MainCtrl.$inject = ['$scope',  'plotData'];

plotData is a custom service i wrote. It use $http to query a database, and retrieve the data I need.

angular.module('myApp.services', []).
factory('plotData', ['$http', function(async) {

    var mainScope = angular.element("#main").scope();

    return {
        send: function(plotType, plotDetail) {
            var thisObj = this;

            var ajaxConfiguration = {
                method: 'POST',
                url: '******************',
                data: { 
                    type: plotType,
                    detail: plotDetail
                }
            };

            async(ajaxConfiguration).
                success(function(data, status, headers, config) {                   
                    mainScope.myVar = data.plot;
                    /* 
                        data.plot is what i expected! 
                        I also try with: return data.plot;
                    */

                }).
                error(function(data, status, headers, config) { 
                    console.info("error"); 
                });
        },
        doSomething: function(data) { },
        doSomethingElse: function() { }
    };

}]);

The problem is that in the controller scope.myVar doesn't change. Basically what i'm trying to do is update a variable defined in the controller from a directive.

What I'm doing wrong?

UPDATE:

@dogoku: As i know i don't need to use $apply because i'm using $http that is still in Angular.

@Mark Rajcok:

0) No, i'm using the real $http service:

factory('plotData', ['$http', function(async) { 
    /* service */ 
}]);

1) yes, i wrote in the code comment. data.plot is what I expected it to be. The backend code works great, so I've not posted it.

2) I will try your link and let you know.

Meanwhile any help is still welcome.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
Bruno
  • 5,961
  • 6
  • 33
  • 52
  • did u try to scope.$digest or scope.$apply after updating? I skimmed through the code, but I don't see it – Dogoku Mar 11 '13 at 22:52
  • 1
    "It use $http to query a database" -- it looks like it is using some `async()` function ?? Also, 1) if you `console.log(data.plot)` do you see your data? 2) getting the scope via a selector then calling `scope()` is not very Angular. A better way would be to send return a promise: see http://stackoverflow.com/questions/12505760/angularjs-processing-http-response-in-service/12513509#12513509 – Mark Rajcok Mar 12 '13 at 00:46
  • @MarkRajcok and Dogoku - I updated the question with the answers to yours comments. – Bruno Mar 12 '13 at 08:14
  • If @Flek's answer doesn't solve your problem, it could be you need to use angular.copy() instead of assignment in your success() callback -- see http://stackoverflow.com/a/15345762/215945 – Mark Rajcok Mar 12 '13 at 14:11
  • @MarkRajcok thank you... the link you suggest (http://stackoverflow.com/questions/12505760/angularjs-processing-http-response-in-service/12513509#12513509) contains the right answer – Bruno Mar 12 '13 at 17:56
  • @MarkRajcok i flagged your comment as useful... if you add an answer, i will accept your answer – Bruno Mar 12 '13 at 17:57

2 Answers2

1

As mentioned in the comments, getting the scope via a selector then calling scope() is not very Angular. A better way would be to return a promise from the service. Pete has a good example of how do to this here: https://stackoverflow.com/a/12513509/215945

angular.copy() should be used instead of assignment in the success() callback, so that the data-binding is not lost in the controller.

See also https://stackoverflow.com/a/15345762/215945

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • I tried the solution suggested in your first comment (http://stackoverflow.com/questions/12505760/angularjs-processing-http-response-in-service/12513509#12513509)... I don't know if this one will work as well. – Bruno Mar 12 '13 at 18:18
0

The only thing that seems suspicious to is how you get the main scope because when I try to call

angular.element('#something');

with AngularJS 1.0.5 or 1.1.3 I get the following error:

selectors not implemented

You can see that here when you open up the developer tools. This would also explain why your scope's property is not updated.

F Lekschas
  • 12,481
  • 10
  • 60
  • 72