Ramin PK
Ramin PK

Reputation: 338

popover with ng-repeat data not showing after ng-click

I have a button to show a popover with loaded data from the server:

<button ng-click="main.getFieldDescriptions()" data-placement="bottom"
        data-toggle="popover" data-container="body"/>

This is an element I want to show as the popover content:

<div id="field-descriptions" class="hide" style="width:500px">
    <div class="row" ng-repeat="f in main.fieldDescriptions">
        <input class="form-control" readonly="true" value="{{f.fieldName}}" />
    </div>
</div>

The data is coming from the server with a get rest request(here is what I have in the controller)

angular.element("#show-fields-description").popover({
    html: true,
    content: function () {
        return angular.element("#field-descriptions").html();
    }
});

this.getFieldDescriptions = function getFieldDescriptions() {
    if (self.report.sysparm_table) {
        return server.get(url)
            .then(function getData(response) {
                self.fieldDescriptions = response.result;
            });
    }
    return null;
};

When the button is clicked popover shows empty content, by the second click it shows the popover with data. It seems popover shows first, then the server values load.

Upvotes: 0

Views: 273

Answers (1)

3960278
3960278

Reputation: 796

You are mixing plane bootstrap popover with angularjs...so $apply/digest cycle of angularjs does not know it.

There are many ways.

  1. Call $apply when modal loaded

  2. Instead of data-toggle on html, call .popover('show') in ng-click callback

  3. use angular ui bootstrap popover

For the first one:

$('#show-fields-description').on('shown.bs.popover', function () {
  main.getFieldDescriptions();

  //Need to call $scope.$apply() after data is there
})

For the second one:

Please see this https://getbootstrap.com/docs/4.3/components/popovers/#options

remove all other attributes from html:

<button ng-click="main.getFieldDescriptions()"></button>
angular.element("#show-fields-description").popover({
    html: true,
    content: function () {
        return angular.element("#field-descriptions").html();
    },
    container: 'body',
    trigger: 'manual',
    placement: 'bottom'
});

and then call show/toggle here:

this.getFieldDescriptions = function getFieldDescriptions() {
    if (self.report.sysparm_table) {
        return server.get(url)
        .then(function getData(response) {
            self.fieldDescriptions = response.result;
            angular.element("#show-fields-description").popover('show');
        });
    }
    return null;
};

Upvotes: 1

Related Questions