1

I want to do bulk delete using angularjs http request to flask restless api version 0.17.0. I know that I can do it one by one, using id of record in url. But I would be pleased if this is possible in one request. I am not sure if this is possible

Flask backend looks like this:

manager.create_api(Messages,
     methods=['GET','PUT','DELETE'], 
     preprocessors={"GET_MANY": [auth_func],
                    "GET_SINGLE": [auth_func],
                    "PUT_SINGLE":[auth_func],
                    "DELETE_SINGLE":[auth_func],
                    "DELETE_MANY":[auth_func] },
     allow_delete_many=True)

My Angularjs code looks like this:

$scope.deleteMails = function(){
    //$scope.deleteMessage = [1,2,3] array of id to delete
    var create_filters = []      
    $scope.deleteMessage.forEach(ele => {            
        create_filters.push({"name": "id", "op": "equals", "val": ele.toString()})
    });        
    $http({
        method  : 'DELETE',
        headers: {'X-CSRFToken' : csrf }, 
        url     : '/api/tbl_messages',
        data : { q : {filters: create_filters} }    
    })
    .then(function(res){
        console.log(res)
    },function(res){
        console.log('error')
    })
}

This request is finished with status 200 but my whole table in db is deleted. In all cases it is deleting my whole DB(table) not concrete ids. I really don't know what to do here. Thank you very much for help in advance.

TomRavn
  • 1,134
  • 14
  • 30

1 Answers1

3

Flask-restless wants the filter passed in the query string-- not as part of the data. That's why it's deleting all your data. It's not picking up the filter at all.

Once that's fixed, you've got an additional problem in your filter itself. You're sending this as your filter:

[ 
  {'name': 'id', 'op': 'equals', 'val': 1},
  {'name': 'id', 'op': 'equals', 'val': 2}
]

A Flask-restless query considers something a match only if all of the filters are a match. In other words, it joins them all with an and:

delete from message where id = 1 and id = 2

You'll either need to tell flask-restless that you want an 'or'

[
  { "or": [
      {"name": "id", "op": "equals", "val": 1},
      {"name": "id", "op": "equals", "val": 2}
  ] }
]

Or change your filter operator to an 'in':

  [  {"name": "id", "op": "in", "val": [1, 2] } ]

Try changing up your angular code to (note the change from data to params):

$http({
    method  : 'DELETE',
    headers: {'X-CSRFToken' : csrf }, 
    url     : '/api/tbl_messages',
    params: { q : JSON.stringify({filters:[{or: create_filters}]}) }    
})

Or-- maybe a bit easier to follow-- change your operator to an 'in' and you can get rid of the forEach:

$http({
    method  : 'DELETE',
    headers: {'X-CSRFToken' : csrf }, 
    url     : '/api/tbl_messages',
    params: { q : JSON.stringify({filters:[{name:'id', op:'in', val: $scope.deleteMessage}]}) }    
})
clockwatcher
  • 3,193
  • 13
  • 13
  • Amazing!!! Thank you very much this is really working. I didn't decipher it from documentation :) Thank you – TomRavn Jun 04 '18 at 09:55