sisimh sisimh - 1 month ago 7
AngularJS Question

Issue in binding service response with html component

I am using a slider component to represent my saved date ranges, I am facing the issue of the slider running before my service returns the HTTP response from backend, therefore I am facing the issue hitting errors in the internal code of the slider library, and my passed values seems not to bind to the directive, and when I initialize the passed array value to have an empty object, I don't face the error but the value is never updated to the service response, can you help me out with what's going on?

Please note that taking the service response and setting it in the initialization of the variable works well.

also adding console.log for the value works too.

HTML :

<multi-slider name="dateSlider"
floor="{{model.dateFloor}}"
step="60"
precision="2"
ceiling="{{model.dateCeiling}}"
bubbles="true"
display-filter="date : 'shortTime'"
reletiveValues="true"
ng-model="model.dateSliders"
style="margin-top:200px">
</multi-slider>
<multi-slider-key ng-model="model.dateSliders" display-filter="date : 'shortTime'"></multi-slider-key>


and in my controller :

$scope.model ={};
$scope.model.testing = [{}];
$scope.model.dateSliders = $scope.model.testing;

var floor = new Date();
floor.setHours(0,0,0,0);
$scope.model.dateFloor = floor.valueOf();

var ceiling = new Date();
ceiling.setHours(24,0,0,0);
$scope.model.dateCeiling = ceiling.valueOf();


userService.getSettings($scope.id, function(err, response) {
if(err) {
$rootScope.showNotificationMessage('danger', err, 10000, true);
} else {
$scope.date = $scope.response.date_ranges;
i = 0;
$scope.testing = [];
angular.forEach($scope.date,function(slider, index){
var newVal = {};
v = angular.copy(slider[0]);

if (index % 2) {
newVal.title = "End:";
newVal.component = 'component' + index;
newVal.value = formatTimeWithCurrentDate(v.end);
} else {
newVal.title = "Start :";
newVal.component = 'component' + index;
newVal.value = formatTimeWithCurrentDate(v.start);
}

$scope.testing.push(newVal);
});

$scope.model.dateSliders = $scope.model.testing;
console.log("GOT RESPONSE");
.....

Answer

The reason is in component itself. I believe you're using this one - https://github.com/enkodellc/angular-multi-slider

In src there is a fragment:

 if (!bindingsSet) {
   setBindings();

   // Timeout needed because bubbles offsetWidth is incorrect during initial rendering of html elements
   setTimeout( function() {
     if ('' + scope.bubbles === 'true') {
       angular.forEach(bubbles, function (bubble) {
          bubble.addClass('active');
       });
     }
     updateCalculations();
     setHandles();

     //Get Default sizes of bubbles and handles, assuming each are equal, calculated from css
     handleTop = handleTop === undefined ? handles[0][0].offsetTop : handleTop;
     handleHeight = handleHeight === undefined ? handles[0][0].offsetHeight : handleHeight;
     bubbleTop = bubbleTop === undefined ? bubbles[0][0].offsetTop : bubbleTop;
     bubbleHeight = bubbleHeight === undefined ? bubbles[0][0].offsetHeight + 7 : bubbleHeight ; //add 7px bottom margin to the bubble offset for handle

     resetBubbles();
   }, 10);
 }

The problem is that this construction doesn't update element (after setBindings function was executed for 1st time). The only way I've found is to use another slider or modify src as follows (move brace to correct place):

 if (!bindingsSet) {
   setBindings();
 }

   // Timeout needed because bubbles offsetWidth is incorrect during initial rendering of html elements
   setTimeout( function() {
     if ('' + scope.bubbles === 'true') {
       angular.forEach(bubbles, function (bubble) {
          bubble.addClass('active');
       });
     }
     updateCalculations();
     setHandles();

     //Get Default sizes of bubbles and handles, assuming each are equal, calculated from css
     handleTop = handleTop === undefined ? handles[0][0].offsetTop : handleTop;
     handleHeight = handleHeight === undefined ? handles[0][0].offsetHeight : handleHeight;
     bubbleTop = bubbleTop === undefined ? bubbles[0][0].offsetTop : bubbleTop;
     bubbleHeight = bubbleHeight === undefined ? bubbles[0][0].offsetHeight + 7 : bubbleHeight ; //add 7px bottom margin to the bubble offset for handle

     resetBubbles();
   }, 10);

Here is a plunker for you (forked from official demo, file changed - multislider.js): http://plnkr.co/edit/DqcAvqNnSyJnXYRpsFT6?p=preview

Comments