0

I have a web application, where I use a third party grid. The grid handles events on its cell in setCellValue, like this:

    $("#productsGridContainer").dxDataGrid({
    dataSource: data,
    keyExpr: "Id",
    allowColumnResizing: true,
    showRowLines: true,
    showBorders: true,
    rowAlternationEnabled: true,
    sorting: true,
    paging: {
        pageSize: 10
    },
    pager: {
        showPageSizeSelector: true,
        allowedPageSizes: [10, 20, 50, 100]
    },
    editing: {
        mode: "row",
        allowUpdating: true,
        allowDeleting: true,
        allowAdding: true
    },
    columns: [
        {
            dataField: "ItemDesc",
            caption: "Description",
            validationRules: [{ type: "required" }]
        },
        {
            dataField: "ItemId",
            caption: "SKU",
            lookup: {
                dataSource: skus,
                displayExpr: "Value",
                valueExpr: "Key"
            },
      setCellValue: function(newData, value, currentRowData) {
        newData.ItemId = value;

        $.ajax({
            type: "POST",
            url: rootDir + "PaaSubmission/GetSkuItemData",
            data: '{ itemId: ' + value + ', custNo: ' + selectedCustomer.val() + ' }',
            contentType: "application/json; charset=utf-8",
            async: false, // if default/true, newData will not be defined in .done
            dataType: "json"
          })
          .done(function(data) {
            newData.ItemDesc = data.Description;
            newData.ItemSize = data.Size;
            newData.ItemOldPrice = data.OldPrice;
          })
          .fail(function(xhr, status, error) {
            displayError("The ajax call to GetSkuItemData() action method failed:",
              JSON.parse(xhr.responseText), "Please see the system administrator.");
          })
      }

As you can see, when the ajax call is done, it is too late to set newData properties. newData is still defined, but it is too late to set it, as setCellValue() is executed by then. THIS MAKES MY QUESTION DIFFERENT from other similar ones. Thus I have to call $ajax() synchronously using async: false. But I know that it is deprecated, as it freezes the browser. Could you please give me an advise on how it can be done without calling $ajax() synchronously?

David Shochet
  • 4,025
  • 10
  • 42
  • 80
  • 1
    This might be informative: [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – showdev Jul 13 '18 at 20:09
  • I would suggest using promise or callback to control the sequence of the asynchronous code as it's a better practice in JavaScript. – user3003238 Jul 13 '18 at 20:11
  • 1
    What happens when you set async to true? Unless I'm mistaken, newData will still be defined, unless the grid source code is throwing it away after the function call. – Erik Philips Jul 13 '18 at 20:13
  • @user3003238 I tried using promise, but it did not help. In fact, as I understand, using done and fail is promise. – David Shochet Jul 13 '18 at 20:13
  • Use setTimout, that should take care of it. – TGarrett Jul 13 '18 at 20:14
  • @Erik Philips Yes, newData is still defined, but it is too late to set it, as setCellValue() is executed by then. I edited my question to make it clear. – David Shochet Jul 13 '18 at 20:15
  • @DavidShochet your comment makes no sense. If it's still exists then it's value can change..... – Erik Philips Jul 13 '18 at 20:17
  • @NappingRabbit I think it is synchronicity problem, as setCellValue() is not waiting for my ajax call to finish, and goes out of scope, of course. – David Shochet Jul 13 '18 at 20:18
  • @DavidShochet so if you console.log(newData) after the `.done()` you see a defined value with the `ItemId` set above the ajax call? – NappingRabbit Jul 13 '18 at 20:19
  • @Erik Philips Of course, the value can change. It just doesn't do the work on the grid, as the event handler ends its execution by then. I may not understand correctly the reason, but the fact is that the grid's event handler doesn't work. – David Shochet Jul 13 '18 at 20:19
  • @DavidShochet OK! so there is more to the story. you need the properties set prior to its consumption! so... use a callback. show more code, and someone will tell you how. – NappingRabbit Jul 13 '18 at 20:21
  • 1
    What `setCellValue` is doing is really not of any value to us if we cannot see the context in which it's being called. It sounds like you need to fetch the data and set the cell values in a callback function. – Tyler Roper Jul 13 '18 at 20:21
  • @DavidShochet Without a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) this question will likely be closed. – Erik Philips Jul 13 '18 at 20:22
  • @Erik Philips I will try to give more information, but you see, it is impossible to give here everything on that 3rd party grid. It is too much. It seems to me that it may be helpful to know that setCellValue handles changing of a grid cell value by the user. By setting newData properties, I can change values of other cells, which correspond to newData's properties, as you can see in the code I provided. And please don't close the question. There may be people who would want to answer. – David Shochet Jul 13 '18 at 20:26
  • @DavidShochet Which third party grid is this? Is there a method to refresh the data, so after you've updated newdata, you can rebind or refresh the affected cells? – Tyler Roper Jul 13 '18 at 20:29
  • @Tyler Roper Don't know if it is possible. It is https://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/ – David Shochet Jul 13 '18 at 20:30
  • @NappingRabbit I don't see how I can use callback here. Maybe it is possible, but I just don't know how. The callback should contain the code that depends on the result of my ajax call, i.e. setCellValue function. But I don't know how it can be detached from its context to be passed to the ajax call. – David Shochet Jul 16 '18 at 12:15
  • 1
    So either the 3rd party grid needs to support the ability to use asynchronous calls or you are sort of out of luck. – epascarello Jul 16 '18 at 12:32
  • @epascarello This is what I also suspected... But at least you said this plainly :) Thanks. – David Shochet Jul 16 '18 at 12:34
  • 1
    https://www.devexpress.com/Support/Center/Question/Details/T545687/dxdatagrid-how-to-call-an-async-method-in-the-setcellvalue-method – epascarello Jul 16 '18 at 12:40
  • @epascarello Yes, I have already found it also. :) But you were the one who made look for it specifically. And as a negative answer if still an answer, would you like to make it actually the answer, so that I could mark it as such? Thanks. – David Shochet Jul 16 '18 at 14:06

0 Answers0