How to delay my ng-init function until my api call is success

809 views Asked by At

I am working on dynamic form with ng-repeat. I am using oi-select for loading my location. I am loading this form inside modal popup. Regarding get my location values i am calling one api function on click of my modal open button. On success of this api call i was calling ng-init method. As per my requirement i should make this api call on click of modal open button. If i am clicking that button at first time, by default my first location value is not loaded inside select-box. Because my ng-init function called before my api call. Other than first time its working fine. Only first time it was not loaded that location[0] value defaultly . My question is how to delay this ng-init function?. Is there any other way to resolve this issue. Here i attached my plunker link .Please help me out from this issue. https://plnkr.co/edit/xDVetaZIzpFdKLS9ihU6?p=preview

html code

<body class="container row">
<div ng-app="myApp">
    <div ng-controller="myCtrl">
        <a class="btn btn-primary" data-toggle="modal" href='#modal-id' ng-click="getLocation()">Trigger modal</a>
        <div class="modal fade" id="modal-id">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                        <h4 class="modal-title">Modal title</h4>
                    </div>
                    <div class="modal-body">
                        <form role="form" name='userForm' novalidate>
                            <div class="container">
                                <div class="row" ng-repeat="user in users">
                                    <div class="form-group">
                                        <div class="col-md-3">
                                            <label>ID</label>
                                            <input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
                                        </div>
                                        <div class="col-md-3">
                                            <label>Comments</label>
                                            <textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
                                        </div>

                                        <div class="col-md-3 ">
                                            <label>Location</label>

                                            <oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>

                                            </oi-select>
                                        </div>
                                    </div>

                                </div>
                            </div>
                            <div class="buttonContainer text-center btn-container">
                                <br>
                                <button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
                                <button type="button" class="btn button--default btn--small pull-center">Close</button>
                            </div>
                        </form>
                    </div>

                </div>
            </div>
        </div>
        <script src="https://code.jquery.com/jquery.min.js"></script>
        <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
        <script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
    </div>
</div>

js code

var app = angular.module('myApp', ['ngResource', 'oi.select']);

app.factory('commonService', function($http, $q) {
return {
    preFCSManualReleases: function() {
        var deferred = $q.defer();
        var url = "data.json";
        $http.get(url, {
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            data: ''
        }).then(function(data) {
            deferred.resolve(data.data);
        });

        return deferred.promise;
    }
}
});
app.controller('myCtrl', function($scope, commonService) {
 $scope.getLocation = function() {
    $scope.ids = [1, 2];
    commonService.preFCSManualReleases().then(function(data) {

        $scope.locations = data;
        console.log('$scope.location[0]==============>', $scope.locations[0])
        $scope.initLocation = (user, locations) => {
            if (!user.location.length) {
                user.location.push(locations[0]);
            }
        }
    });

    $scope.users = $scope.ids.map(function(id) {
        return {
            id: id,
            comment: "",
            location: []
        };
    });
}
$scope.adduser = function() {
    var data = $scope.users.map(function(user) {

        return {
            "userid": user.id,
            "manualcomment": user.comment,
            "location": user.location
        }
    });

    console.log("data", data)

 }

  });
1

There are 1 answers

0
edo.n On

You can put a condition on the oi-select parent:

<div class="col-md-3" ng-if="locationsLoaded">
    <label>Location</label>

    <oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>

    </oi-select>
</div>

You can then control the $scope.locationsLoaded in your controller:

$scope.getLocation = function() {
  $scope.locationsLoaded = false;
  commonService.preFCSManualReleases().then(function(data) {

      $scope.locations = data;
      console.log('$scope.location[0]==============>', $scope.locations[0])
      $scope.initLocation = (user, locations) => {
          if (!user.location.length) {
              user.location.push(locations[0]);
          }
      }

      $scope.locationsLoaded = true; // we now have the required data
  });
}

The ng-if will compile the element once locationsLoaded is true and when the ng-init is triggered, you are sure that there is data.