Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Server side start with twice request #102

Closed
giolvani opened this issue Oct 21, 2014 · 23 comments
Closed

Server side start with twice request #102

giolvani opened this issue Oct 21, 2014 · 23 comments

Comments

@giolvani
Copy link

I'm using with server side processing and when it initializes, the request to server is duplicated.

<table datatable dt-options="dtOptions" dt-columns="dtColumns"></table>
$scope.dtOptions = DTOptionsBuilder.newOptions()
  .withOption('ajax', { url: String.format('{0}api/System/Message/Get', BASEURL) })
  .withDataProp('data')
  .withOption('serverSide', true)
  .withOption('processing', true)
  .withOption('order', [[0, 'asc'], [1, 'asc']])
  .withBootstrap();

$scope.dtColumns = [
  DTColumnBuilder.newColumn('cdMessage').withTitle('Id').withOption('width', 110),
  DTColumnBuilder.newColumn('cdCulture').withTitle('Culture').withOption('width', 100),
  DTColumnBuilder.newColumn('tpMessage').withTitle('MessageType').withOption('width', 160),
  DTColumnBuilder.newColumn('dsMessage').withTitle('MessageDescription'),
  DTColumnBuilder.newColumn('dsDetails').withTitle('MessageDetails')
];

Firebug request

@l-lin
Copy link
Owner

l-lin commented Oct 21, 2014

What version of angular-datatables are you using?

@giolvani
Copy link
Author

v0.2.1

@l-lin
Copy link
Owner

l-lin commented Oct 21, 2014

Mmh...weird, I don't reproduce your issue... Is it related to #101?

@giolvani
Copy link
Author

I think it's not related, cause even if I use this way, keep the issue...

$scope.dtOptions = DTOptionsBuilder.newOptions()
   .withOption('ajax', { url: String.format('{0}api/System/Message/Get', BASEURL) })
   .withDataProp('data')
   .withOption('serverSide', true);

@giolvani
Copy link
Author

In angular-datatables.js at line 375

$scope.$watch('[dtOptions, dtColumns, dtColumnDefs]', function (newVal, oldVal) {
  if (newVal !== oldVal) {
      var newDTOptions = newVal[0], oldDTOptions = oldVal[0];
      // Do not rerender if we want to reload. There are already
      // some watchers in the renderers.
      if (!newDTOptions.reload || newDTOptions.sAjaxSource !== oldDTOptions.sAjaxSource) {
          //IT PASS HERE 2x
          ctrl.render($elem, ctrl.buildOptions(), _staticHTML);
      } else {
          // The reload attribute is set to false here in order
          // to recall this watcher again
          newDTOptions.reload = false;
      }
  }
}, true);

I console.log it, and I saw it pass 2x... Is it right?

@l-lin
Copy link
Owner

l-lin commented Oct 22, 2014

I made a Plnkr and it's not calling twice. Can you edit this plnkr to reproduce your issue?

@giolvani
Copy link
Author

I'll try!

2014-10-22 16:07 GMT-02:00 Louis LIN [email protected]:

I made a Plnkr http://embed.plnkr.co/MksjdyLmMxCG1FjSUEmo/ and it's not
calling twice. Can you edit this plnkr to reproduce your issue?


Reply to this email directly or view it on GitHub
#102 (comment)
.

Att.
Giolvani de Matos

@kbeaugrand
Copy link

Hi,
I've tried to fix this issue, and I think that I've a potential solution.
In the AjaxRenderer class, the method render is looking for 'dtOptions.sAjaxSource' changes, but systematicly call the render even if the sAjaxSource is undefined.

I fixed this bug by placing the line

_render(options, $elem, $scope);

inside the

if (angular.isDefined(sAjaxSource)) {

condition.

Here is the final result :

 $scope.$watch('dtOptions.sAjaxSource', function (sAjaxSource) {
              if (angular.isDefined(sAjaxSource)) {
                _this.options.sAjaxSource = sAjaxSource;
                if (angular.isDefined(_this.options.ajax)) {
                  if (angular.isObject(_this.options.ajax)) {
                    _this.options.ajax.url = sAjaxSource;
                  } else {
                    _this.options.ajax = { url: sAjaxSource };
                  }
                }
                _render(options, $elem, $scope);
              }
            });

But I don't know if there was a specific reason to have the render outside the condition ??

Dear,

@giolvani
Copy link
Author

giolvani commented Nov 6, 2014

It doesn't worked for me!

I saw that at line 1089

if (oTable) {
    var ajaxUrl = options.sAjaxSource || options.ajax.url || options.ajax;
    oTable.ajax.url(ajaxUrl).load();
} else {
    oTable = DTRendererService.renderDataTableAndEmitEvent($elem, options, $scope);
}

When the component starts, it passes sequentially in the 'else' and soon after the 'if'.

@kbeaugrand
Copy link

That's right!

This is cause by the watch statements :

$scope.$watch('dtOptions.sAjaxSource', function (sAjaxSource) {
              if (angular.isDefined(sAjaxSource)) {
                _this.options.sAjaxSource = sAjaxSource;
                if (angular.isDefined(_this.options.ajax)) {
                  if (angular.isObject(_this.options.ajax)) {
                    _this.options.ajax.url = sAjaxSource;
                  } else {
                    _this.options.ajax = { url: sAjaxSource };
                  }
                }
                _render(options, $elem, $scope);
              }
            });
            $scope.$watch('dtOptions.reload', function (reload) {
              if (reload) {
                $scope.dtOptions.reload = false;
                _render(options, $elem, $scope);
              }
            });

In fact Angular JS notifies that dtoOptions.sAjaxSource has changed (but it's undefined), then AngularJs notifies that dtoOptions.reload has changed (because that's the first load I think.

In reallity, you have 2 calls to the _render method sequentially....

That's why the first call passed by the else statement and the second by the if statement (the oTable has been initialized by the first call).

I Moved the _render method because sAjaxSource is always undefined because I used the { url: '', method: 'post' } configuration instead.

Dear

@giolvani
Copy link
Author

giolvani commented Nov 6, 2014

Where you changed the code? Remove or replace something?
I couldn't reproduce your change here! :(

@kbeaugrand
Copy link

OK,

I'm using V0.2.0 and my changes were made on line 1047.

           $scope.$watch('dtOptions.sAjaxSource', function (sAjaxSource) {
              if (angular.isDefined(sAjaxSource)) {
                _this.options.sAjaxSource = sAjaxSource;
                if (angular.isDefined(_this.options.ajax)) {
                  if (angular.isObject(_this.options.ajax)) {
                    _this.options.ajax.url = sAjaxSource;
                  } else {
                    _this.options.ajax = { url: sAjaxSource };
                  }
                }
              }
              _render(options, $elem, $scope);
            });

Was changed to :

          $scope.$watch('dtOptions.sAjaxSource', function (sAjaxSource) {
              if (angular.isDefined(sAjaxSource)) {
                _this.options.sAjaxSource = sAjaxSource;
                if (angular.isDefined(_this.options.ajax)) {
                  if (angular.isObject(_this.options.ajax)) {
                    _this.options.ajax.url = sAjaxSource;
                  } else {
                    _this.options.ajax = { url: sAjaxSource };
                  }
                }
                _render(options, $elem, $scope);
              }
            });

@giolvani
Copy link
Author

giolvani commented Nov 6, 2014

Oh man, i am using v0.2.1, and this code snippet does not exists anymore!

:(

@kbeaugrand
Copy link

Sorry,

I'm trying with V0.2.1. But i've got some errors. I come back to you after fixing it.

@kbeaugrand
Copy link

OK,

I tested with V0.2.1 and it looks good :) thank you.

@giolvani
Copy link
Author

giolvani commented Nov 7, 2014

With V0.2.1 this problem was solved to you?

@kbeaugrand
Copy link

Yes but i've got anothre bug using the reloadData functionnality but I cannot isolate the root cause

@lukaszpaczos
Copy link

This issue was solved?
Because I have the same problem. I'm using v0.3.0

@l-lin
Copy link
Owner

l-lin commented Nov 27, 2014

I do not reproduce the issue. See screenshot:
image

If any of you manage to reproduce the problem on a plnkr, I'll gladly check what's wrong.

@giolvani
Copy link
Author

You're right!
The problem is that I can not reproduce this issue in plunkr or something
like, but I will keep trying...

2014-11-27 11:33 GMT-02:00 Louis LIN [email protected]:

I do not reproduce the issue. See screenshot:
[image: image]
https://cloud.githubusercontent.com/assets/5452304/5217563/3527229c-7642-11e4-8723-887581fc71e1.png

If any of you manage to reproduce the problem on a plnkr, I'll gladly
check what's wrong.


Reply to this email directly or view it on GitHub
#102 (comment)
.

Att.
Giolvani de Matos

@JakubKahovec
Copy link

I'm having the same issue (on 0.2.1 as well as 0.3.0), data get loaded twice. Data are being loaded through a promise. The issue actually causes that when the table state is being saved on reload I get pagination info lost.

screen shot 2014-12-02 at 09 26 23

@ralphite
Copy link

Hi, I'm seeing the same issue in v0.4.3.

@dashawk
Copy link

dashawk commented Aug 17, 2017

It is because of the promises.

In the first load of your page, you must set the tableOptions and tableColumns with an empty promise.

// I personally don't like this approach. It should have been handled by the directive already
vm.tableOptions = $q.defer().promise;
vm.tableColumns = $q.defer().promise;

// After Loading the DOM, add your options
vm.tableOptions = DTOptionsBuilder ... // or $resource().query().$promise;
vm.tableOptions = DTColumnsBuilder ... // or $resource().query().$promise;

This is what I noticed, if the DOM is not yet ready, the tableOptions will attempt to call for an ajax request, but since the <table datatable is not yet present, it will not do anything, you just be able to see the request first hand, then after the DOM is loaded, then the datatable directive will start the tableOptions to call for an ajax request, that is why there are two requests after the page load.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants