Prevent ajax request from duplicating

3,390 views
Skip to first unread message

Sergey Chico

unread,
Jun 4, 2013, 9:13:14 AM6/4/13
to ang...@googlegroups.com
I have an issue with multiple ajax requests. For example I have form with submit button. When I hit the submit button multiple times I there is multiple ajax requests. How can I prevent ajax requests while there is still no callback from first one? The temporary solution is to disable the submit button till callback. But this solution is against DRY principle because I have to write nearly same code for every form/button in multiple controllers. Does anyone knows another solution?

Grant Rettke

unread,
Jun 4, 2013, 1:56:52 PM6/4/13
to ang...@googlegroups.com
We did the low-tech thing and put a busy image over the entire screen
during http requests. It ain't perfect but it is a start.
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to angular+u...@googlegroups.com.
> To post to this group, send email to ang...@googlegroups.com.
> Visit this group at http://groups.google.com/group/angular?hl=en-US.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
Grant Rettke | ACM, AMA, COG, IEEE
gre...@acm.org | http://www.wisdomandwonder.com/
“Wisdom begins in wonder.” --Socrates
((λ (x) (x x)) (λ (x) (x x)))
“Life has become immeasurably better since I have been forced to stop
taking it seriously.” --Thompson

Martin Grotzke

unread,
Jun 4, 2013, 2:15:18 PM6/4/13
to ang...@googlegroups.com

What about a directive for a button that disables the button when it's clicked?

Cheers,
Martin

Am 04.06.2013 15:13 schrieb "Sergey Chico" <chi...@gmail.com>:
I have an issue with multiple ajax requests. For example I have form with submit button. When I hit the submit button multiple times I there is multiple ajax requests. How can I prevent ajax requests while there is still no callback from first one? The temporary solution is to disable the submit button till callback. But this solution is against DRY principle because I have to write nearly same code for every form/button in multiple controllers. Does anyone knows another solution?

--

Sergey Chico

unread,
Jun 4, 2013, 2:26:07 PM6/4/13
to ang...@googlegroups.com, martin....@googlemail.com
There is already ng-disabled directive in angular. That not solves the DRY problem.

вторник, 4 июня 2013 г., 22:15:18 UTC+4 пользователь Martin Grotzke написал:

Sergey Chico

unread,
Jun 4, 2013, 2:32:09 PM6/4/13
to ang...@googlegroups.com, gre...@acm.org
This solution not work for our application. Application must work while any ajax request is sended. I thought of disabling form as component that way. But this solution still not DRY. Polymer integration into Angular will be great. At least component disabling logic can be encapsulated.

вторник, 4 июня 2013 г., 21:56:52 UTC+4 пользователь Grant Rettke написал:

Jason Stone

unread,
Jun 4, 2013, 10:27:04 PM6/4/13
to ang...@googlegroups.com
I would keep a cache of the $http promise, and clear it when the promise resolves.
That way you can reuse the cache if it's available, or watch it to run your `ngDisabled` directives.

chico

unread,
Jun 5, 2013, 3:57:49 AM6/5/13
to ang...@googlegroups.com
This not works if you (for example) create new record in DB on promise resolve ( .then(<...>) part). If you click submit button twice you will have two records created.


2013/6/5 Jason Stone <rola...@gmail.com>
I would keep a cache of the $http promise, and clear it when the promise resolves.
That way you can reuse the cache if it's available, or watch it to run your `ngDisabled` directives.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/79UiXuRKuIU/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.

Jason Stone

unread,
Jun 6, 2013, 9:37:39 PM6/6/13
to ang...@googlegroups.com
Fair point.

If I understand correctly, what you want is something you can bind the 'ng-disabled' directive to on all your UI components, in the DRYest possible manner.
So you have a single service to make the $http call, and multiple controllers and templates to handle the various views.

You can still have your service return the $http promise, but before it does that, it could set a "inProgress" property on the promise.
eg.

function getData() {
  var promise = $http.get(url);
  promise.inProgress = true;
  promise.then(function () {promise.inProgress = false;}, function () {promise.inProgress = false;});
  return promise;
};

Your controller can attach the promise to the $scope, so it can be watched.
eg.

function MyCtrl($scope, myService) {
  $scope.onClick = function () {
    $scope.lastCall = myService.getData();
    // ... Sets it's own 'then.()' callbacks, etc.
  };
}

And then your template uses 'ng-disabled' to prevent any click events from triggering until the previous call is finished.
eg.

<button ng-disabled="lastCall.inProgress" ng-click="onClick()">Submit</button>

Alternatively, you could use a "if (!$scope.lastCall.inProgress)" test in your controller method rather than using a ng-disabled.
But it's better to give the user some feedback to let them know subsequent clicks won't do anything.

Ron G.

unread,
Jun 6, 2013, 11:24:55 PM6/6/13
to ang...@googlegroups.com
It seems to me that, in most cases, the multiple clicks will be by people mistakenly thinking they have to double click. Capture ng-dblClick by having it execute a function that pops up a dialog box saying something to the effect, "Please wait. Your request is being processed." In addition, for those cases where someone waits a longer time so it appears as two single clicks, rather than a double click, why not create a custom button directive that handles checking the last component clicked, If the function, perhaps within the directive's controller, determines that the same component (button) was clicked twice, it can handle it the same as ng-dblClick. This keeps you from violating the DRY principle because it's the same directive being used multiple places, if needed. 
Reply all
Reply to author
Forward
0 new messages