Naren Murali Naren Murali - 2 months ago 5
Ajax Question

Allow only one flask request for a particular route

I have a flask app which uses angularjs front end. I make the http request through $http service. As shown in the code below.

$http.post('/updateGraph', $scope.graphingParameters).success(function(response) {
$scope.graphingParameters.graph = response.graph;
$scope.listUnits = JSON.parse(response.listUnits);
$scope.myHTML = $sce.trustAsHtml($scope.graphingParameters.graph);
$scope.showME = true;
})


and the updateGraph function in flask is as follows.

@app.route('/updateGraph', methods = ['POST'])
def updateGraph():
selectValues = request.json['selectValues']
selectSelected = np.array(request.json['selectSelected']).tolist()
if len(selectSelected) == 0:
selectSelected = np.array([selectValues[1:3]]).tolist()
fig, listUnits = plot_Stock_vs_Sales(selectSelected)
graph = py_offline.plot(fig, include_plotlyjs=False, output_type='div', show_link=False)
return json.dumps({ 'graph': graph, 'listUnits':listUnits.reset_index().to_json(orient='records')})


The problem is that suppose make the $http post from angular twice, The flask route is running twice. this is the code from the server.



Seconds:92
127.0.0.1 - - [12/Sep/2016 09:46:35] "POST /updateGraph HTTP/1.1" 200 -
Seconds:110
127.0.0.1 - - [12/Sep/2016 09:47:02] "POST /updateGraph HTTP/1.1" 200 -


I want to either make the $http post request to only allow one request or make flask run only one route per user. Is this possible through flask? if not what would be the best approach through angular?

Answer

From your description of the situation, this is something that would be better solved on the client side.

I would just set a flag (define it on a global or class level) if there's a request already ongoing for that task. For example:

if (processing) {
    return;
}
processing = true;
$http.post('/updateGraph', $scope.graphingParameters).success(function(response) {
        $scope.graphingParameters.graph = response.graph;
        $scope.listUnits = JSON.parse(response.listUnits);
        $scope.myHTML = $sce.trustAsHtml($scope.graphingParameters.graph);
        $scope.showME = true;
        processing = false;
    })

This implementation can also be used to hide/disable the button or whatever triggers the request from the user so that they cannot trigger it while there's an ongoing request.

Note that I'm not very familiar with angular 1, so you might want to trigger that processing = false after the request and not only on success.