it indeed was because it's inside the nonangular bind() event, putting scope.$apply()
after http and before resolve will fix it
https://github.com/angular/angular.js/issues/1159#issuecomment-20368490
el.bind('keyup', function() {
var canceler = $q.defer();
$http.post('/api', data, {timeout: canceler.promise}).success(success);
scope.$apply();
canceler.resolve();
});