0

I am not sure what the issue is, but it seems the datatables directive is being initialized before my $scope is defined. What's more, it seems the variables getting set twice.

I have a userService that retrieves the column definitions and data from my server. The getUserList() method returns a promise. I use the then() method to set the $scope variables that will be used by the datatables directive. It seems the directive is requesting the variables before the request completes. Also, it seems the variables are getting set twice, because in Chrome's dev console I see the "test" log twice.

If I use static data (not coming from the server) and place the $scope variables outside the getUserList() promise it works fine.

    $scope.indexList = function () {
                userService.getUserList().then(function (data) {


                    $scope.dtOptions = DTOptionsBuilder.fromFnPromise(function () {
                        console.log("test"); 
                        var deferred = $q.defer();
                        deferred.resolve(data.Data);
                        return deferred.promise;
                    });
                    $scope.dtColumns = [];

                    angular.forEach(data.DataTablesColumns, function (i, v) {
                        $scope.dtColumns.push(DTColumnBuilder.newColumn(i.Id)
                                              .withTitle(i.DisplayName)
                                              .renderWith(actionsHtml));
                    });

                });
            }

This is how I am setting the datatables directive:

    <div ng-init="indexList()">
        <table datatable="" dt-options="dtOptions" dt-columns="dtColumns"class="row-border hover"></table>
    </div>
DDiVita
  • 4,225
  • 5
  • 63
  • 117

2 Answers2

1

The directive code is executed as soon as the page loads. And since your $scope variables are defined in the promise, they are not available at the time of page load.

The directive does not wait for the request to complete because requests are async in nature. If you want the directive variable to be updated when the request completes you have to set a $watch(or $watchGroup if you want to watch multiple variables) on the $scope.variables in your link function as follows:

link: function(scope, element, attrs) {
    scope.$watch('dtOptions', function(newval, oldval) {
        //your directive code involving scope variables here.
    })
}
Tarun Dugar
  • 8,921
  • 8
  • 42
  • 79
0

It seems I have to make 2 calls to my server to do what I am after. This works, but I feel there should be a way to make a single call to the server and get back then entire result. After some reading the options and column builders can take a promise.

$scope.indexList = function () {


            $scope.dtOptions = DTOptionsBuilder.fromFnPromise(function () {
                return userService.getUserList(ngRequestGlobabls.context.organization).then(function(data) {
                    return data.Data;
                });
            });


            $scope.dtColumns = userService.getUserList(ngRequestGlobabls.context.organization).then(function (data) {
                columns = [];
                angular.forEach(data.DataTablesColumns, function(i, v) {
                    columns.push(DTColumnBuilder.newColumn(i.Id).withTitle(i.DisplayName).renderWith(actionsHtml));
                });

                return columns;
            });
DDiVita
  • 4,225
  • 5
  • 63
  • 117