ajax option function infinite recursion

ajax option function infinite recursion

jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

I am trying to use the ajax option, passing it a function: ajax: (data, callback, settings) => { ... };

I am using this along with serverSide: true in order to make AJAX calls myself and then just calling the callback with the results. I discovered I have to call the callback with an object that looks like this: callback({ data: results }). Otherwise, I get an error saying data is undefined. The docs don't make this clear, since it is just sending back a parsed local storage "thing".

The problem I am running into is that the same call seems to be getting made repeatedly with the same start and length parameters. It will keep doing this until the browser says "Too much recursion". I tried including recordsTotal and recordsFiltered values but that didn't help.

If it helps, I am using this along side the deferRender, scroller, and paging.

Answers

  • colincolin Posts: 15,143Questions: 1Answers: 2,586

    It would be worth looking at the examples for serverSide. If they don't help, we're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Colin

  • jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

    I think I made some progress on this. It looks like the my ajax function is getting called with every draw operation. I select some rows programmatically after calling the callback, which kicks off another draw, which calls the callback and so on. I guess I am surprised with this behavior; I would only expect the ajax function to get called when the next batch of rows is needed. Perhaps I need to cache the results based on the start parameter? I am not sure.

    I found this page to be very helpful for seeing what datatables is expecting as a return value: https://datatables.net/manual/server-side

  • kthorngrenkthorngren Posts: 20,300Questions: 26Answers: 4,769

    ajax function is getting called with every draw operation.

    With serverSide processing enabled that is expected. The server script is responsible for determining the rows to display each draw.

    I select some rows programmatically after calling the callback, which kicks off another draw

    How are you selecting the rows. If using the Select Extension with the select() doesn't call draw() as shown here:
    http://live.datatables.net/sayobomo/1/edit

    Are you doing something else when selecting the row that calls draw()?

    Kevin

  • jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

    I explicitly call draw after performing a select, using the select extension, yeah. I assumed it was necessary, but now that I am reading the documentation again I don't see anywhere it says that.

  • jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

    I actually re-learned why I was calling draw. I wasn't seeing the selection info updating next to the rest of the paging info (i). Calling draw was the only way I could get it refresh the info section. If there was a less intense API call to force it to update, that could work, I just don't know what it is.

    For now, I have some logic in place to check if the data passed from one call to the next is identical to the previous and just send back the previous results along with the new draw id.

    I noticed if I simply ignore the request (a.k.a., never call the callback) that after a handful of requests they just stop altogether. I assumed this is to prevent hammering the server. I wasn't sure if this was part of datatables or just an artifact of it running in the browser. It'd be nice if there was a way to pass something to the callback to tell it to do nothing. Not sure if that's a thing.

    I was also curious if there was a way to tell when the data sent to the callback has been loaded and the screen fully drawn, similar to the callback parameter of the ajax.reload function. Right now I am using the on('draw') event but curious if that's the best route.

  • kthorngrenkthorngren Posts: 20,300Questions: 26Answers: 4,769

    I wasn't seeing the selection info updating next to the rest of the paging info

    That's expected when using select(). See Colin's comment, in this thread about this and a link to the Select code that does display the selected information if not done by the API.

    You can take that code and implement your own info element and remove the need to use draw().

    Kevin

  • jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

    Ha, yeah, that was me. I ended up with this helper method:

    getSelectionInfo = () => {
        // Out-of-the-box DataTables does not display the selection count when
        // selection is controlled entirely by the API. So we must manually write
        // the counts in that case. So, if selection is enabled, we allow the
        // out-of-the-box behavior to occur; otherwise, we simulate it ourselves.
        if (
          this.table == null ||
          this.props.selectable ||
          !this.props.showSelectionInfo
        ) {
          return '';
        }
        const selectedCount = this.getSelectedCount();
        if (selectedCount === 0) {
          return '';
        }
        const name = this.props.selectionMode || SELECTION_MODE_ROW;
        const message = this.table.i18n(
          `select.${name}s`,
          { _: `%d ${name}s selected`, 0: '', 1: `1 ${name} selected` },
          selectedCount
        );
        return ` (${message})`;
      };
    

    I guess the next step is to use jQuery to hunt down the .dataTables_Info div, if present, and append that to the text, rather than relying on draw. That cuts down one need to call draw. Let me roll with that and see if I am still having excessive calls to load data.

  • kthorngrenkthorngren Posts: 20,300Questions: 26Answers: 4,769

    Sorry, didn't notice that was your thread :smile: Just remembered the discussion.

    Kevin

  • jehugaleahsajehugaleahsa Posts: 11Questions: 3Answers: 0

    No, it was good to retrace my steps in order to eliminate unnecessary draws. Thanks for giving me another idea. I'll share what I did once I get it working.

This discussion has been closed.