Search code examples
angularjsangular-uiangular-ui-grid

Saving row data with AngularJS ui-grid $scope.saveRow


I'm working on a small frontend application which will show various product shipping data in a ui-grid.

I have the following code:

HTML:

<body ng-controller="MyCtrl">

    <p ng-repeat="row in myData">{{row.name}} works at {{row.company}}</p>

    <button type="button" class="btn btn-success" ng-click="getCurrentFocus()">Get Current focused cell</button>  <span ng-bind="currentFocused"></span>
    <br/>
    <br/>
    <div id="grid1" ui-grid="gridOptions" external-scopes="editRows" ui-grid-edit ui-grid-row-edit ui-grid-pinning ui-grid-paging ui-grid-cellnav class="grid"></div>

</body>

AngularJS:

var app = angular.module('webapps', ['ngAnimate', 'ui.grid', 'ui.grid.edit', 'ui.grid.rowEdit', 'ui.grid.pinning', 'ui.grid.paging', 'ui.grid.cellNav']);

app.controller('MyCtrl', ['$scope', '$http', '$q', '$interval', function ($scope, $http, $q, $interval) {

 //Column definitions
    $scope.columns = [
        { field: 'name', displayName: 'First Name', width: 300},
        { field: 'lastname', displayName: 'Last Name', width: 300 },
        { field: 'email', displayName: 'Email', width: 300 },
        { field: 'company', displayName: 'Company', width: '50%' }
    ];

    //Options for displaying the grid
    $scope.gridOptions = {
        data: 'myData',
        enableCellEditOnFocus: false,
        pagingPageSizes: [2, 5, 7],
        pagingPageSize: 5,
        enableSorting: true,
        enableGridMenu: true,
        columnDefs: $scope.columns,
        onRegisterApi: function (gridApi) {
            $scope.gridApi = gridApi;
            //var cellTemplate = '<button class="btn primary" ng-click="getExternalScopes().showMe(rowCol.row.entity)">Edit</button>'; //'ui-grid/selectionRowHeader';   // you could use your own template here
            //$scope.gridApi.core.addRowHeaderColumn({ name: 'rowHeaderCol', displayName: '', width: 50, pinnedLeft: true, cellTemplate: cellTemplate });
            gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
        }
    };

    // Save row data on edit 1 - TESTING
    $scope.saveRow = function (rowEntity) {
        // create a fake promise - normally you'd use the promise returned by $http or $resource
        var promise = $http.post("Webapps/Home/SaveRow");
        $scope.gridApi.rowEdit.setSavePromise($scope.gridApi.grid, rowEntity, promise.promise);
        console.log(rowEntity);

        // fake a delay of 3 seconds whilst the save occurs, return error if gender is "male"
        $interval(function () {
            if (rowEntity.lastname === ' ') {
                promise.reject();
            } else {
                promise.resolve();
            }
        }, 3000, 1);
    };
}]); // End of MyCtrl

My question is in regards to the $scope.saveRow method. I've looked over the documentation here and tried searching on google (not much out there for ui-grid) but I'm still hitting a dead end as I'm a bit inexperienced with this and I'm not sure how to code this properly with promises.

There will be an MVC app running behind this which will handle pushing the data to the front end and saving table edits to a SQLServer db. Obviously what I'd like to do is have this $scope.saveRow function properly send the rowEnttiy data back to my MVC app but, again, I'm at a loss for how to code the function. The "fake" promises included in the example aren't enough for me to get a grasp on what I need to do, apparently. I initially tried the following:

$scope.saveRow = function (rowEntity) {
    try {
        // Need actual URL for post...controller has to accept 'row'
        $http.post("Webapps/Home/SaveRow", { row: rowEntity }).success(function (data, status, headers, config) {
            console.log("post success");
            console.log(rowEntity);
        }).error(function (data, status, headers, config) {
            console.log("post failure");
            console.log(rowEntity);
        });
    } catch (e) {
        alert("Something went wrong");
    }
};

but this only throws an exception in my console that a promise was not returned when the saveRow event is raised.


Solution

  • You would normally do the promise/api call in a separate repository, but basically the code you are looking for is something like this:

     $scope.saveRow = function( rowEntity ) {
    
        var promise = $scope.someRepositoryFunction(rowEntity);
        $scope.gridApi.rowEdit.setSavePromise($scope.gridApi.grid, rowEntity, promise);
    
        // fake a delay of 3 seconds whilst the save occurs, return error if gender is "male"
        //$interval( function() {
        //    if (rowEntity.firstName === 'male' ){
        //        promise.reject();
        //    } else {
        //        promise.resolve();
        //    }
        //}, 3000, 1);
    };
    
    $scope.someRepositoryFunction = function(row) {
        return $http.put('/Home/UpdateRow',row);
    }