title: Saving HandsOnTable data with Flask
body: <p>I'm trying to load and save data from a <a href="http://handsontable.com/" rel="nofollow">HandsOnTable</a> using Flask. I'm following <a href="http://docs.handsontable.com/tutorial-load-and-save.html" rel="nofollow">these instructions</a> for loading and saving (retrieving and sending) data using ajax. I have managed to get data to load into the table from a URL that returns a JSON dictionary, but I haven't figured out how to send data do store in my database.</p>
  
  <p>Here is what the relevant part of the javascript looks like:</p>
  
  <pre><code>Handsontable.Dom.addEvent(save, 'click', function() {
      // save all cell's data
      ajax('/json/save.json', 'GET', JSON.stringify({data: hot.getData()}), function (res) {
        var response = JSON.parse(res.response);
  
        if (response.result === 'ok') {
          exampleConsole.innerText = 'Data saved';
        }
        else {
          exampleConsole.innerText = 'Save error';
        }
      });
    });
  </code></pre>
  
  <p>So hopefully that is taking the data from the HandsOnTable, turning it into a big JSON table of this format:</p>
  
  <pre><code>{'data' : [[row 1], [row 2],...]}
  </code></pre>
  
  <p>And here is what the relevant Flask view function looks like:</p>
  
  <pre><code>@app.route('/json/save.json', methods = ['GET', 'POST'])
  @login_required
  def jsonSave():
      data = request.form['data']
      #Do stuff to load data into database
      return 'ok'
  </code></pre>
  
  <p>With irrelevant parts removed. Basically my question is how do I make the <code>data = request.form['data']</code> part of the save function work, and turn it into a simple list of rows? </p>
  
  <p>Incidentally, part of why this is difficult is that I can't see what exactly is being sent to the view function with the ajax call. Is there a way I can see that so I can more easily debug issues like this? Print statements don't seem to work in view functions (I can't see them in the console).</p>
  
  <p>Thanks a lot,
  Alex</p>
  
  <p><strong>Update</strong> Changed (again) as per ZekeDroid's instructions to:</p>
  
  <pre><code>Handsontable.Dom.addEvent(save, 'click', function() {
  // save all cell's data
  console.log(JSON.stringify({data: hot.getData()}));
  ajax('/json/save/{{well['id']}}', 'POST', JSON.stringify({data: hot.getData()}), function (res) {
    var response = JSON.parse(res.response);
  
    if (response.result === 'ok') {
      exampleConsole.innerText = 'Data saved';
    }
    else {
      exampleConsole.innerText = 'Save error';
    }
  });
  </code></pre>
  
  <p>});</p>
  
  <p>and</p>
  
  <pre><code>@app.route('/json/save/&lt;int:well_id&gt;', methods = ['GET', 'POST'])
  @login_required
  def jsonSave(well_id):
      jsonData = request.get_json()
      print 'jsonData:', jsonData
      data = jsonData['data']
      print 'data:', data
      #Insert table into database
      print 'saving', well_id
      return json.dumps(True)
  </code></pre>
  
  <p><strong>Debug output</strong>:
  Basically, it looks like Flask is not loading a json object when it calls <code>jsonData = request.get_json()</code>. The <code>console.log(JSON.stringify({data: hot.getData()}));</code> looks ok, however.</p>
  
  <p>Here is the output from the browser and Flask consoles:</p>
  
  <p>Browser:</p>
  
  <pre><code>{"data":[["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],[null,null,null,null,null]]}
  samples.js:94 POST http://127.0.0.1:5000/json/save/1 500 (INTERNAL SERVER ERROR)
  </code></pre>
  
  <p>Flask:</p>
  
  <pre><code>jsonData: None
  127.0.0.1 - - [13/May/2015 11:41:31] "POST /json/save/1 HTTP/1.1" 500 -
  Traceback (most recent call last):
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1836, in __call__
      return self.wsgi_app(environ, start_response)
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1820, in wsgi_app
      response = self.make_response(self.handle_exception(e))
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1403, in handle_exception
      reraise(exc_type, exc_value, tb)
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1817, in wsgi_app
      response = self.full_dispatch_request()
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1477, in full_dispatch_request
      rv = self.handle_user_exception(e)
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1381, in handle_user_exception
      reraise(exc_type, exc_value, tb)
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1475, in full_dispatch_request
      rv = self.dispatch_request()
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
  1461, in dispatch_request
      return self.view_functions[rule.endpoint](**req.view_args)
    File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask_login.py", lin
  e 758, in decorated_view
      return func(*args, **kwargs)
    File "C:\Users\aschmitt\Dropbox\Python\PetroTools\app\views.py", line 236, in
  jsonSave
      data = jsonData['data']
  TypeError: 'NoneType' object has no attribute '__getitem__'
  </code></pre>