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
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.
Data was getting inserted before the $http.post
request 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.
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}
.
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)
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);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With