Maik
Maik

Reputation: 3

AngularJS, jQuery ajax request, always have to request (click) twice

I allready tried to search the anwser... I'm stuck.

I try communicating between controllers (http://onehungrymind.com/angularjs-communicating-between-controllers/).

This works fine for me.

In next step i tried to add an ajax request, which result should be send to controllers.

The request is doing his job, but unfortunately only on every second request.

AJAX-Request

var request = $.post("http://www.mydomain.com/search.php", { data: "" });
    request.done(function( data ) {
        sharedService.prepForBroadcast(data);
    });
};

What is going wrong with this?

JAVASCRIPT

var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {

    var sharedService = {};
    sharedService.message = '';

    sharedService.prepForBroadcast = function(msg) {
        this.message = msg;
        this.broadcastItem();
    };

    sharedService.broadcastItem = function() {
        $rootScope.$broadcast('handleBroadcast');
    };

    return sharedService;
});

function Controller($scope, sharedService) {

    $scope.handleClick = function() {

        var request = $.post("http://www.mydomain.com/search.php", { data: "" });
        request.done(function( data ) {
            sharedService.prepForBroadcast(data);
        });
    };

    $scope.$on('handleBroadcast', function() {
        $scope.message = 'zero: ' + sharedService.message;
    });
}

function ControllerOne($scope, sharedService) {
    $scope.$on('handleBroadcast', function() {
        $scope.message = 'ONE: ' + sharedService.message;
    });        
}

function ControllerTwo($scope, sharedService) {
    $scope.$on('handleBroadcast', function() {
        $scope.message = 'TWO: ' + sharedService.message;
    });
}

Controller.$inject = ['$scope', 'mySharedService'];        
ControllerOne.$inject = ['$scope', 'mySharedService'];
ControllerTwo.$inject = ['$scope', 'mySharedService'];

HTML

<script type='text/javascript' src="http://code.angularjs.org/angular-1.0.0rc9.js"></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>

<body ng-app="myModule">

    <div ng-controller="Controller">
        <button ng-click="handleClick();">read json</button>
    </div>

    <div ng-controller="ControllerOne">
        <input ng-model="message" >
    </div>

    <div ng-controller="ControllerTwo">
        <input ng-model="message" >
    </div>

Thank you.

Upvotes: 0

Views: 4250

Answers (1)

pkozlowski.opensource
pkozlowski.opensource

Reputation: 117370

The problem is that your code is executed outside of the "AngularJS world". To be precise any external event that should trigger 2-way data binding should trigger AngularJS $digest loop. See http://docs.angularjs.org/guide/concepts for more on this.

Now, coming back to your particular problem, you've got 2 solutions:

  1. Drop jQuery ajax in favor of AngularJS $http service. This is a preferred solutions, it is easier and nicer: from jquery $.ajax to angular $http

  2. Wrap your call in the $scope.$apply method to trigger a $digest loop when the jQuery call is finished

But really, just let go of jQuery...

Upvotes: 8

Related Questions