Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data pushing into table(array) before success in angularjs xeditable table

I want to insert the added data into table only after the post request is successful, but it will add before checking the post request. So how do I insert the table row data only after success.

Also, showCategories (categories gotten from the api) is not working, but gender (getting from local) is working. In select box (category data options is showing) but I cannot select the category data. I used same thing as gender select box, but gender select box is working but not category. Where did I make my mistake?

Html

 <table class="table table-bordered table-hover table-condensed">
        <tr style="font-weight: bold">
            <td style="width:5%">No.</td>
            <td style="width:20%">Name</td>
            <td style="width:10%">Gender</td>
            <td style="width:30%">Profile photo</td>
            <td style="width:20%">Category</td>
            <td style="width:30%">Action</span>
            </td>
        </tr>
        <tr ng-repeat="user in users">
            <td>{{$index+1}}</td>
            <td>
                <span editable-text="user.name" e-name="name" onbeforesave="checkName($data, user._id)" ng-model="userName" e-form="rowform" e-required>
                      {{ user.name}}
                    </span>
            </td>
            <td>
            <span editable-select="user.gender" ng-model="gender" e-name="gender" e-form="rowform" e-ng-options="s.value as s.text for s in genders">
                  {{ showGender(user) }}
            </span>

            </td>

            <!-- ng-show="tableform.$visible" -->
            <td class="text-center" >
                    <img ng-src="/api/media/{{user.media_id}}" alt="No Image" style="margin-bottom:20px;width:100%;">
                    <a class="btn btn-success" ui-sref="media({_id: user._id })" style="border: .0625rem solid transparent;margin: 10px 0px;padding: .465rem 1rem;"> Upload File</a>
                <!-- <input type="file" flow-button   value="Upload"> -->
            </td>
            <td>
                 <span editable-select="user.category" e-name="category" e-form="rowform" e-ng-options="c.value as c.name for c in categories">
                  {{ showCategories(user) }}
                 </span> 
            </td>
            <td style="white-space: nowrap">
                <!-- form -->
                <form editable-form name="rowform" onbeforesave="saveUser($data,user_id)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == user">
                    <button type="submit" ng-disabled="rowform.$waiting" class="btn btn-primary">
                        save
                    </button>
                    <button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
                        cancel
                    </button>
                </form>
                <div class="buttons" ng-show="!rowform.$visible">
                    <button class="btn btn-primary" ng-click="rowform.$show()">edit</button>
                    <button class="btn btn-danger" ng-click="deleteUser(user)">delete</button>
                </div>
            </td>
        </tr>
    </table>

and controller

.controller('mainCtrl', function($scope, $stateParams, $timeout, userService, categoryService, $filter, $q, verifyDelete, $window, $rootScope, $http, $state, $mdDialog) {
    categoryService.init(function(category_response) {
        $scope.categories = category_response.data.result;
        $scope.category = JSON.parse(JSON.stringify(getCategory($stateParams._id)));
        console.log($scope.category);
    });

    function getCategory(id) {
        for (var i = 0; i < $scope.categories.length; i++) {
             console.log(i);
            if ($scope.categories[i]._id === id) {

                return $scope.categories[i];

            }
        }
        return {
            name: ''
        };
    }

    userService.init(function(user_response) {
        $scope.users = user_response.data.data;
    });


    $scope.genders = [{
        value: 'male',
        text: 'Male'
    }, {
        value: 'female',
        text: 'Female'
    }];

    $scope.loadCategories = function() {
        return $scope.categories.length ? null : $http.get('/api/categories/list').success(function(data) {
            $scope.categories = data;
        });
    };
$scope.showGender = function(user) {
var selected = [];
if(user.gender) {
   selected = $filter('filter')($scope.genders, {value: user.gender});
}
return selected.length ? selected[0].text : 'Not set';
 };


  $scope.showCategories = function(user) {
        var selected = [];
        if (user.category_id) {
            selected = $filter('filter')($scope.categories, {
                category_id: user.category_id
            });
        }
        console.log(selected);
         return selected.length ? selected[0]._id : 'Not set';
    };

  $scope.saveUser = function(user) {
    // console.log(name);
    if(user._id){

        $http.put('/api/users/'+user._id, user, $scope)
        .then(function(response) {
          $state.reload();
             }, function(response) {

            });

    }
    else{
        $http.post('/api/users/', user, $scope)
        .then(function(response) {
            $state.reload();

             }, function(response) {
                $scope.errorMessage=response.data;
                 $scope.errorValMessage = true;
                $timeout(function () {
                $scope.errorValMessage = false;
                }, 2000);



            });

    }
 };
$scope.addUser = function(user) {
$scope.inserted = {
    name:'',
     gender:null,
     email:'',
     password:'',
    re_password:'',
    category:null
};
$scope.users.push($scope.inserted);
};


})
.run(function(editableOptions) {
    editableOptions.theme = 'bs3';
});

api data for users

 {"total_rows":2,"start":0,"data":[{"_id":"572c7696d17dde185e059390","name":"aaaaaaaaaaa","gender":"female","email":"","password":"","re_password":"","category_id":"ordinary"},{"_id":"572c76c3d17dde185e059392","name":"cccccccccc","gender":"male","email":"","password":"","re_password":"","category_id":"ordinary"}]}

Can anyone please help me. Thanks in advance

like image 453
codelearner Avatar asked May 06 '16 08:05

codelearner


2 Answers


So, when I saw the plunker yesterday there were 4 problem in it. and I've fixed all of them. Here is working and tested plunker also please read the following to understand what exactly was wrong.


Problem No 1: Data pushing in tables before success request

Data was getting inserted before the $http.postrequest response, since xeditable automatically saves the data weather the status code behind the scenes is 400 or 200. In case of status code 400 (failure) the inserted item will be deleted from the front table and in case of success the request will be processed as desired. I've used Angular-Mocks to intercept the $http.post('/saveUser', data) request because it does NOT exist in real time on plunker.

How To check If it really works:

Intercepting the Post Request:

app.run(function($httpBackend)
{
    $httpBackend.whenPOST(/\/saveUser/).respond(function(method, url, data)
    {
    data = angular.fromJson(data);
    //return [404, {status: 'error'}];
    return [200, {status: 'ok'}];
});

above mentioned is the code to intercept the http.post request I've set two return statements, only ONE must be left uncommented.

Fail the Request by: If the statement with {status: 'error'} is uncommented the and vice versa than the insertion will be failed and new row will be deleted automatically.

success the request by If the return statement having this status code {status: 'ok'} is running the every thing will go smoothly and data will be inserted.


Problem No 2: Categories Not Working

The categories were NOT getting selected because in $scope.showCategories = function you were using {value: user.category_id} category_id where as it should have been {value: user.category}.


Problem No 3: Delete is NOT working either.

Delete was NOT working because in your HTML you are passing user to deleteUser function as following:

ng-click="deleteUser(user)

Where as It should have been this:

ng-click="deleteUser($index)

Problem No 4: On Cancel Empty row is Inserted.

When a new row is added and then clicked cancel it was leaving an empty row in the table. so I've wrote a new function to perform both the cancel jobs of (Cancel for New Insertion) and (Cancel for Edited Data). You could add more validations to this function but the basic idea is there.

Here is the function which either remove a newly added row and than cancel is clicked or editing an old record and clicked cancel.

$scope.cancelit = function(rowform, index)
{
    console.log(rowform, index);
    if(rowform.$data.name !== '')
    {
      rowform.$cancel();
    }
    else
    {
      $scope.deleteUser(index);
    }
}

like image 172
Wcan Avatar answered Nov 15 '22 08:11

Wcan


The categories problem:
The ideal situation is to let your server handle the joining of the user table and the categories list. The server's job is to give your front-end data in a decent format. After all, the server should be far more powerful than the user's computer. You should be able to just call {{users.category}}. BUT suppose this is not possible for whatever reason. You now have to loop through your categories list to find where user.category === category.value like:

$scope.showCategories = function(user) {
    angular.forEach($scope.categories, function(category) {
        if(user.categories == category.value) {
             return category.value;
        }
    }
};

The unsaved rows problem:

This is more of a display problem than a flow problem. You don't need your users list to only be updated after the server is, you just want it to accurately reflect what's in the server. I'm not familiar with x-editable, but you can get what you want by making the cancel button's ng-click action be a function on $scope does the cleanup on your users list, then does the $cancel action in the x-editable API that it currently does.

If, for some reason, you're against having it in your table at all until it's in the DB, then you'll probably want to make addUser() populate a temporary user variable, have the cancel button zero out that variable, and your HTML show that row only if the variable is set.

like image 41
C.C. Avatar answered Nov 15 '22 10:11

C.C.