Search code examples
angularjsangular-ui

Angularjs ui-modal is not working properly with $http request


I am using Angularjs 1.5.x and AngularUI Bootstrap

I am trying to open a bootstrap modal and populate it with remote data using $http request.

I am using resolve method of modal's open instance to trigger $http request and fetch the data. After that I am updating a local variable and return it. However, the $http is fetching data properly but local scope variable is not updating properly and its keep showing as empty array in template.

Code:

app.controller('ModalCtrl', function ($uibModal, $log, $document, $rootScope, $http) {
      var $cctrl = this;

      $cctrl.modalData = [];

      $cctrl.animationsEnabled = true;

      $cctrl.open = function (size, templateUrl, parentSelector) {
         var parentElem = parentSelector ?
            angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
         var modalInstance = $uibModal.open({
            animation: $cctrl.animationsEnabled,
            ariaLabelledBy: 'modal-title',
            ariaDescribedBy: 'modal-body',
            templateUrl: templateUrl,
            controller: 'ModalInstanceCtrl',
            controllerAs: '$cctrl',
            size: size,
            appendTo: parentElem,
            resolve: {
               modalData: function () {
                  var url;
                  var reqData;
                  var config = {
                     headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'responseType': 'json',
                        'cache': false
                     }
                  };

                  if (templateUrl == 'test.html') {
                     reqData = $.param({
                        lclasses: ($rootScope.activeTruck.truck.LicenceClassesRequired || ''),
                        subbie: ($rootScope.activeTruck.truck.subbie || '0')
                     });

                     url = 'index.php?module=test&task=fetchJSON';
                  }

                  $http.post(url, reqData, config).then(function (response) {
                     console.log("Success");
                     console.log(response); //here, response fetched data success
                     $cctrl.modalData = response.data;
                     console.log($cctrl.modalData); //here, its [] data 
                     return $cctrl.modalData;
                  }, function (response) {
                     console.log("Failed");
                     console.log(response);
                  });
               }
            }
         });

         modalInstance.result.then(function (selectedItem) {
            console.log("opened");
         }, function () {
            $log.info('Modal dismissed at: ' + new Date());
         });
      };
   });

// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.

   app.controller('ModalInstanceCtrl', function ($uibModalInstance, modalData) {
      var $cctrl = this;
      console.log(modalData);
      $cctrl.modalData = modalData;

      $cctrl.ok = function () {
         //$uibModalInstance.close($cctrl.selected.item);
         $uibModalInstance.close();
      };

      $cctrl.cancel = function () {
         $uibModalInstance.dismiss('cancel');
      };
   });

Solution

  • Here it's working fine...

    angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
    angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
    var $cctrl = this;
    
      $cctrl.items = [
        {
            "id": 0,
            "picture": "https://ultimatemotorcycling.com/wp-content/uploads/2011/11/2012-ducati-panigale-1199-preview-5.jpg",
            "age": 31,
            "name": "Mathews Goff",
            "company": "FXA"
        },
        {
            "id": 1,
            "picture": "http://placehold.it/32x32",
            "age": 36,
            "name": "Collins Alston"
        },
        {
            "id": 2,
            "picture": "http://placehold.it/32x32",
            "age": 27,
            "name": "Jasmine Rollins"
        },
        {
            "id": 3,
            "picture": "http://placehold.it/32x32",
            "age": 32,
            "name": "Julie Jefferson"
        },
        {
            "id": 4,
            "picture": "http://placehold.it/32x32",
            "age": 23,
            "name": "Wilder King"
        },
        {
            "id": 5,
            "picture": "http://placehold.it/32x32",
            "age": 23,
            "name": "Stanley Moore"
        },
        {
            "id": 6,
            "picture": "http://placehold.it/32x32",
            "age": 36,
            "name": "Reynolds Bishop"
        },
        {
            "id": 7,
            "picture": "http://placehold.it/32x32",
            "age": 26,
            "name": "Bryant Flowers"
        },
        {
            "id": 8,
            "picture": "http://placehold.it/32x32",
            "age": 38,
            "name": "Jenifer Martinez"
        },
        {
            "id": 9,
            "picture": "http://placehold.it/32x32",
            "age": 40,
            "name": "Mcguire Pittman"
        },
        {
            "id": 10,
            "picture": "http://placehold.it/32x32",
            "age": 34,
            "name": "Valdez Hyde"
        },
        {
            "id": 11,
            "picture": "http://placehold.it/32x32",
            "age": 34,
            "name": "Marla Mayo"
        },
        {
            "id": 12,
            "picture": "http://placehold.it/32x32",
            "age": 30,
            "name": "Brown Ortega"
        },
        {
            "id": 13,
            "picture": "http://placehold.it/32x32",
            "age": 32,
            "name": "Jeannette William"
        },
        {
            "id": 14,
            "picture": "http://placehold.it/32x32",
            "age": 30,
            "name": "Bridges Ashley"
        },
        {
            "id": 15,
            "picture": "http://placehold.it/32x32",
            "age": 33,
            "name": "Latasha Hewitt"
        },
        {
            "id": 16,
            "picture": "http://placehold.it/32x32",
            "age": 35,
            "name": "Alma Sawyer"
        },
        {
            "id": 17,
            "picture": "http://placehold.it/32x32",
            "age": 21,
            "name": "Liz Mcbride"
        },
        {
            "id": 18,
            "picture": "http://placehold.it/32x32",
            "age": 26,
            "name": "Mcintosh Chandler"
        },
        {
            "id": 19,
            "picture": "http://placehold.it/32x32",
            "age": 20,
            "name": "Alford Hartman"
        },
        {
            "id": 20,
            "picture": "http://placehold.it/32x32",
            "age": 29,
            "name": "Tiffany Green"
        },
        {
            "id": 21,
            "picture": "http://placehold.it/32x32",
            "age": 38,
            "name": "Stafford Riggs"
        },
        {
            "id": 22,
            "picture": "http://placehold.it/32x32",
            "age": 40,
            "name": "Elinor Chambers"
        },
        {
            "id": 23,
            "picture": "http://placehold.it/32x32",
            "age": 27,
            "name": "Carly Howard"
        },
        {
            "id": 24,
            "picture": "http://placehold.it/32x32",
            "age": 27,
            "name": "Rosalind Sanchez"
        },
        {
            "id": 25,
            "picture": "http://placehold.it/32x32",
            "age": 28,
            "name": "Jaclyn Shelton"
        },
        {
            "id": 26,
            "picture": "http://placehold.it/32x32",
            "age": 25,
            "name": "Hughes Phelps"
        },
        {
            "id": 27,
            "picture": "http://placehold.it/32x32",
            "age": 36,
            "name": "Rosetta Barrett"
        },
        {
            "id": 28,
            "picture": "http://placehold.it/32x32",
            "age": 29,
            "name": "Jarvis Wong"
        },
        {
            "id": 29,
            "picture": "http://placehold.it/32x32",
            "age": 23,
            "name": "Kerri Pennington"
        }
    ];
    
      $cctrl.open = function (size) {
    
        var modalInstance = $uibModal.open({
          templateUrl: 'myModalContent.html',
          controller: 'ModalInstanceCtrl',
          controllerAs:'$cctrl',
          resolve: {
            items: function () {
              return $cctrl.items;
            },
            size: function() {
             // console.log('size: ', size);
              return size;
            }
          }
        });
    
      };
    });
    
    // Please note that $modalInstance represents a modal window (instance) dependency.
    // It is not the same as the $modal service used above.
    
    angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items, size) {
    var $cctrl = this;
      $cctrl.items = items;
      $cctrl.selected = {
        item: $cctrl.items[0]
      };
      $cctrl.size = size;
     // console.log('size in ctrl: ', size);
    
      $cctrl.ok = function () {
        $uibModalInstance.close($cctrl.selected.item);
      };
    
      $cctrl.cancel = function () {
        $uibModalInstance.dismiss('cancel');
      };
    });
    <!doctype html>
    <html ng-app="ui.bootstrap.demo">
      <head>
      <style>
      .grid {
        border: solid 1px #ccc padding: 10px 10px 0 0;
    }
    .grid li {
        display: inline-block;
        width: 100px;
        height: 200px;
        border: solid 1px #ccc;
        margin: 0 0 10px 10px;
        background: #eee;
    }
    
    /**** Transitions ****/
    
    .masonry,
    .masonry li { /* apply before masonry add class */
        position: absolute; /* important to add it before enter animation start */
        
        -webkit-transition-duration: .7s;
        transition-duration: .7s;
        
        -webkit-transition-property: all;
        transition-property: all;
    }
    
    .masonry .masonry-enter { /* limit animated properties for entering elements */
        -webkit-transition-property: -webkit-transform, opacity;
        transition-property: transform, opacity;
    }
    
    .masonry-enter,
    .masonry-leave.masonry-leave-active {
        opacity: 0;
        -webkit-transform: scale(0.1);
        transform: scale(0.1);
    }
    
    .masonry-leave,
    .masonry-enter.masonry-enter-active {
        opacity: 1;
        -webkit-transform: scale(1);
        transform: scale(1);
    }</style>
      <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/masonry/2.1.08/jquery.masonry.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
        <!--<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>-->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
        <script src="example.js"></script>
        <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
        <link href="style.css" rel="stylesheet">
      </head>
      <body>
      
      <div ng-controller="ModalDemoCtrl as ctrl">
          <input type="text" ng-model="nameFilter" />
          <a href="#" ng-click="order = 'id'">Order by id</a>
          <a href="#" ng-click="order = 'name'">Order by name</a>
          <a href="#" ng-click="order = 'age'">Order by age</a>
      
          <ul class="grid" masonry="true">
              <li ng-repeat="item in ctrl.items | filter: { name: nameFilter } | orderBy: order">
                  <span>{{item.name}}</span>
                  <br /> <span>Age: {{item.age}}</span>
                  <br /> <span>Company: {{item.company}}</span>
                  <img ng-src="{{item.picture}}" width="100" ng-click="ctrl.open(item)"/>
              </li>
          </ul>
      </div>
    
    
        <script type="text/ng-template" id="myModalContent.html">
            <div class="modal-header">
                <h3 class="modal-title">I'm a modal!</h3>
            </div>
            <div class="modal-body">
                {{$cctrl.size.name}} {{$cctrl.selected}}
            </div>
            <div class="modal-footer">
                <button class="btn btn-primary" ng-click="$cctrl.ok()">OK</button>
                <button class="btn btn-warning" ng-click="$cctrl.cancel()">Cancel</button>
            </div>
        </script>
    
        
      </body>
    </html>

    Try like below..

    $http.post(url, reqData, config).then(function (response) {
     return response.data; //return your response data directly
    }
    

    In ModalInstanceCtrl controller you can get like below.

      $cctrl.modalData = modalData;