0

I have an issue where I can't get to a variable inside a function:

EDIT I forgot to add that I am setting this workerPage.grid = $("#grid").data("kendoGrid"); on the jQuery $(function(){});

I can't use claimsGird variable inside the save function, I have to referenec it by workerPage.grid. Not the other variables like viewModel work fine. Here is the snippet:

save = function () {
                saif.kendoGridUtils.addModifiedDataItems(
                    viewModel.CompanionClaims.Updated,
                    viewModel.CompanionClaims.Added,
                    $("#grid").data("kendoGrid").dataSource.data()
                );

                $.ajax({
                    url: $("#contentForm").attr("action"),
                    data: JSON.stringify(viewModel),
                    type: "POST",
                    contentType: "application/json"
                }).success(function (data) {
                    //syncs viewModel with changes in model
                    $.extend(viewModel, kendo.observable(data));

                    //rebinds the grid data source
                    claimsGrid.dataSource.data(viewModel.CompanionClaims.Rows);

Here is the full script:

var workerPage = (function () {
        var viewModel = kendo.observable(@Html.Raw(Json.Encode(Model))),
            claimsGrid = null,
            deleteFirm = function (firmModel) {
                firmModel.Name = "";
                firmModel.AttorneyName = "";
                firmModel.Address.Line1 = "";
                firmModel.Address.Line2 = "";
                firmModel.Address.City = "";
                firmModel.Address.State = "OR";
                firmModel.Address.ZipCode = "";
                firmModel.Address.PlusFourCode = "";
                firmModel.PhoneNumber = "";
                firmModel.FaxNumber = "";
                firmModel.ContactName = "";
            },
            bind = function () {
                kendo.bind($("#main-content"), viewModel);
            },
            save = function () {
                saif.kendoGridUtils.addModifiedDataItems(
                    viewModel.CompanionClaims.Updated,
                    viewModel.CompanionClaims.Added,
                    $("#grid").data("kendoGrid").dataSource.data()
                );

                $.ajax({
                    url: $("#contentForm").attr("action"),
                    data: JSON.stringify(viewModel),
                    type: "POST",
                    contentType: "application/json"
                }).success(function (data) {
                    //syncs viewModel with changes in model
                    $.extend(viewModel, kendo.observable(data));

                    //rebinds the grid data source
                    claimsGrid.dataSource.data(viewModel.CompanionClaims.Rows);


                    //rebinds view elements to view model so changes are visible
                    //kendo.bind($("#main-content"), viewModel);
                    bind();

                    // Errors and Warnings
                    var results = messageUtils.parseMessages(
                        viewModel.Messages.Errors,
                        viewModel.Messages.Informationals,
                        viewModel.Messages.Warnings
                    );

                    var errs = $("#errors").html(results.errorMessages);
                    $("#informationals").html(results.informationalMessages);
                    $("#warnings").html(results.warningMessages);

                    $.each(saif.kendoGridUtils.processErrors(viewModel.CompanionClaims.Rows), function (i, message) {
                        errs.html(errs.html() + message + "<br>");
                    });
                    // End Errors and Warnings

                });
            },
            deleteRow = function () {
                var row = claimsGrid.select(),
                    rowDataItem = claimsGrid.dataItem(row),
                    rowIndex = $(row).index(),
                    addedItemIndex = $.inArray(rowDataItem, viewModel.CompanionClaims.Added);

                //add to Deleted if not new
                if (addedItemIndex == -1 && $.inArray(rowDataItem, viewModel.CompanionClaims.Rows) != -1) {
                    viewModel.CompanionClaims.Deleted.push(rowDataItem);
                }

                //remove from Added if exists
                if (addedItemIndex != -1) {
                    viewModel.CompanionClaims.Added.splice(addedItemIndex, 1);
                }

                claimsGrid.removeRow(row);

                //select the next row, eg. if you delete row 2, select the row that took that rows poisition after it was deleted.
                claimsGrid.select(claimsGrid.tbody.find(">tr:eq(" + rowIndex + ")"));
            };

        return {
            bind: bind,
            deleteFirm: deleteFirm,
            deleteRow: deleteRow,
            grid: claimsGrid,
            save: save,
            viewModel: viewModel
        };

    }());
2
  • The only assignment to the claimsGrid variable is claimsGrid = null. Have you missed to show some of the code? Commented Jan 23, 2013 at 19:47
  • @nekman - Yes, please see my edit above. Commented Jan 23, 2013 at 20:28

2 Answers 2

2

The issue is that claimsGrid is never set to anything other than null. And setting workerPage.grid won't change the value of claimsGrid -- it's not a pointer, just a copy.

You'll instead have to use a getter/setter. With newer browsers/engines, that can be done with get and set:

// ...
return {
    // ...
    get grid() {
        return claimsGrid;
    },
    set grid(grid) {
        claimsGrid = grid;
    },
    // ...
};

You can also define grid as a function:

// ...
function getOrSetGrid(grid) {
    if (typeof newGrid === 'undefined') {
        return claimsGrid;
    } else {
        claimsGrid = grid;
    }
}

return {
    // ...,
    grid: getOrSetGrid,
    // ...
};
// ...
// rather than: workerPage.grid = ...;
workerPage.grid(...);

Or split it into getGrid and setGrid functions.

Sign up to request clarification or add additional context in comments.

4 Comments

I forgot to add that I am setting this workerPage.grid = $("#grid").data("kendoGrid"); on the jQuery $(function(){});
@SamStriano Since you were including claimsGrid in the "reveal," I assumed that was the case. But, as I noted, setting workerPage.grid won't affect claimsGrid -- "it's not a pointer, just a copy."
Could you elaborate on "it's not a pointer, just a copy"? Maybe a link somewhere that explains this a little better? Thanks!!
@SamStriano workerPage.grid doesn't have any ties back to claimsGrid beyond being the source of its initial value (the copy). It doesn't hold a reference to claimsGrid in any way (as a pointer would). They are instead entirely separate variables that just so happen to have the same value for a time. But, setting one to a new value won't be reflected in the other since they are separate.
0

Scope in javascript works differently than other languages like Java or C#. In your case claimsGrid is not in scope for the save function. Does this help? http://coding.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.