serge
serge

Reputation: 15249

Angular Module popup: How to obtain data from Ajax/Json

I have mainly to open an angular popup window based on a template. But I need to obtain the data from an ajax call.

The Module sample explains how to use a template, but I am confused where to place an ajax call to obtain the items, like follows (the snippet is not working, but is the same as the sample):

angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl',
    function($scope, $uibModal, $log) {

      //
      // need to obtain these items from an AJAX/GET call
      //
      $scope.items = ['item1', 'item2', 'item3'];

      $scope.open = function(size) {
          var modalInstance = $uibModal.open({
            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl',
            size: size,
            resolve: {
              items: function() {
                return $scope.items;
              }
            }
          });
<div ng-controller="ModalDemoCtrl">
  <script type="text/ng-template" id="myModalContent.html">
    <div class="modal-header">...</div>
    <div class="modal-body">
      <ul>
        <li ng-repeat="item in items">...</li>
      </ul>
    </div>
    <div class="modal-footer">...</div>
  </script>

  <button type="button" ng-click="open()">Open me!</button>

</div>

I have a link that return JSON data, I'd modify the function like this:

      $scope.open = function(size, jsonLink) {
          var modalInstance = $uibModal.open({

            // ?????
            templateJsonUrl: jsonLink,
            // ?????

            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl',
            size: size,
            resolve: {
              items: function() {
                return $scope.items;
              }
            }
          });

Upvotes: 3

Views: 1260

Answers (2)

Alexandr Lazarev
Alexandr Lazarev

Reputation: 12892

Just make a request with a http service, and assign result to $scope.items when it will be resolved. A digest cycle will make bindings. Don't forget to inject http service itself.

angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl',
    function($scope, $http, $uibModal, $log) {

      $http
          .post('/your_pass_to_json.json', data)
          .then(function(data) {
              $scope.items = data.items;
          });

      $scope.open = function(size) {
          var modalInstance = $uibModal.open({
            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl',
            size: size,
            resolve: {
              items: function() {
                return $scope.items;
              }
            }
          });

Here is plunker, but I've assigned $scope.items in the promise rejection because could not mock the XHR request.

UPDATE

Or you can put modal opening in the xhr callback:

$scope.open = function(size) {
    $http
    .post('/your_pass_to_json.json', data)
    .then(function(data) {
        var modalInstance = $uibModal.open({
            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl',
            size: size,
            resolve: {
              items: function() {
                return data.tiems;
              }
            }
       });
   });
}

In this case, the modal will always be opened with a delay. I would suggest you to make an xhr request once the controller was initialized, and make a verification on the opening event: if xhr was already fired before, take items from $scope, if it wasn't, cancel previous request and make a new one.

Upvotes: 3

İsmail Şener
İsmail Şener

Reputation: 423

@Lazarev's answer is correct, but additionally in Angular, you have to make ajax calls from angular services and directly inject to controllers.

like this; AngularJS Ajax Call in Service

Upvotes: 1

Related Questions