rodney757
rodney757

Reputation: 583

Angular UI Bootstrap modal display during $http request

I am trying to create a directive that uses angular ui bootstrap modal. I would like to open this directive from my controller when a $http request is made, and close it when the request resolves. I'm new to angular and a bit stuck. Here's what I've got so far.

expedition.html controller:

.controller('ExpeditionCtrl', ['$http', 'UserFactory', '$scope',
    function ($http, UserFactory, $scope) {
        var vm = this;
        vm.totalItems;
        vm.itemsPerPage = 100;
        vm.currentPage = 1;
        vm.pageChanged = pageChanged;
        vm.content = [];
        vm.loadingInstance;
        vm.open;
        fetchPage();

        function pageChanged() {
            fetchPage();
        }

        function fetchPage() {

            $http.get('myapi?page=' + vm.currentPage + "&limit=" + vm.itemsPerPage)
                .then(function(response) {
                    angular.extend(vm.content, response.data.content);
                    vm.content = response.data.content;
                    vm.totalItems = response.data.totalElements;
                })
        }

    }

expedition.html:

<div class="section">
    <div class="sectioncontent">
        // some html

            <uib-pagination total-items="vm.totalItems" ng-model="vm.currentPage" ng-change="vm.pageChanged()" items-per-page="vm.itemsPerPage"></uib-pagination>

        </div>
        <loading-modal loadingInstance="vm.loadingInstance" open="vm.open"></loading-modal>
    </div>
</div>

loadingModal.directive.js:

.directive('loadingModal', ['$uibModal',
    function($modal) {
        return {
            transclude: true,
            restrict: 'EA',
            template: '<div ng-init="open()"> Test Loading </div>',
            scope: {
                loadingInstance: "=",
                open: "="
            },
            link: function(scope, element, attrs) {

                scope.open = function(){

                    scope.loadingInstance = $modal.open({
                        templateUrl: 'app/templates/loadingModal.tpl.html',
                        controller:  scope.useCtrl,
                        size: 'sm',
                        windowClass: 'app-modal-window',
                        backdrop: true,

                    });
                    scope.loadingInstance.result.then(function(){
                        scope.initialized = true;
                        console.log('Finished');
                    }, function(){
                        scope.initialized = true;
                        console.log('Modal dismissed at : ' + new Date());
                    });
                };
            }
        };
    }]);

loadingModal.tpl.html:

<div class="modal-body">
    Loading ....
</div>

Upvotes: 1

Views: 2087

Answers (2)

rodney757
rodney757

Reputation: 583

Ok, so I was able to do this by using a factory. Then in the controller, I call LoadingModalFactory.open() when I initiate a $http request, and LoadingModalFactory.modalInstance.close() when the request resolves. Maybe there's a better way to do this, but for now this is working.

.factory('LoadingModalFactory', ['$uibModal', function($uibModal) {
    var modalInstance;
    var loadingModalFactory = {
        open: open,
        modalInstance: modalInstance,
    };

    return loadingModalFactory;

    function open() {
        loadingModalFactory.modalInstance = $uibModal.open({
            templateUrl: 'app/components/modals/templates/loadingModal.tpl.html',
            size: 'sm',
            windowClass: 'app-modal-window',
            backdrop: true,

        });
    }

}]);

Upvotes: 2

C.C.
C.C.

Reputation: 575

In your fetchPage() function:

  1. Open the modal and return its object to a variable
  2. Run the $http call and in the resolution, close the modal with its stored variable reference

var modal = $uibModal.open({ //your modal config }); $http.get(...).then(function(response) { modal.close(); });

I may be going outside of the question, but you don't have to do this in a directive. You can still modularize this by using a template for the modal and a controller for the modal defined elsewhere.

If you need to do this in a directive, you could pass the http get function into the directive with the '&' scope property.

Upvotes: 1

Related Questions