handsontable Error: loadData only accepts array of objects or array of arrays (undefined given)

56 Views Asked by At

I can not figure out why data is not binding and loading the handsontable. The user would enter in course number and section, and click display grades button. A fetch would retrieve the data from an sqlite database and return the rows from the database query. According to handsontable i must send loadData an array of arrays.

When I run the app I get these 4 print statements

  1. update student grades for course

  2. <class 'list'> [{'stg_st_number': 1111, 'stg_crs_number': 'MAT101', 'stg_crs_section': 'B', 'stg_st_semester': '2023X', 'stg_g1': 80, 'stg_g2': 75, 'stg_g3': 71, 'stg_g4': None, 'stg_g5': None, 'stg_g6': None, 'stg_g7': None, 'stg_g8': None, 'stg_g9': None, 'stg_g10': None, 'stg_final': None}, {'stg_st_number': 2222, 'stg_crs_number': 'MAT101', 'stg_crs_section': 'B', 'stg_st_semester': '2023X', 'stg_g1': 81, 'stg_g2': 76, 'stg_g3': 72, 'stg_g4': 74, 'stg_g5': 75, 'stg_g6': 76, 'stg_g7': 77, 'stg_g8': 78, 'stg_g9': 79, 'stg_g10': 80, 'stg_final': None}]

  3. <class 'list'> [[1111, 'MAT101', 'B', '2023X', 80, 75, 71, None, None, None, None, None, None, None, None], [2222, 'MAT101', 'B', '2023X', 81, 76, 72, 74, 75, 76, 77, 78, 79, 80, None]]

  4. <class 'flask.wrappers.Response'> <Response 305 bytes [200 OK]>

And the browser console shows I’m passing an array of arrays

  1. (2) [Array(15), Array(15)]
  2. 0: Array(15)
  3. 0: 1111
  4. 1: "MAT101"
  5. 2: "B"
  6. 3: "2023X"
  7. 4: 80
  8. 5: 75
  9. 6: 71
  10. 7: null
  11. 8: null
  12. 9: null
  13. 10: null
  14. 11: null
  15. 12: null
  16. 13: null
  17. 14: null
  18. length: 15
  19. [[Prototype]]: Array(0)
  20. 1: (15) [2222, 'MAT101', 'B', '2023X', 81, 76, 72, 74, 75, 76, 77, 78, 79, 80, null]
  21. length: 2
  22. [[Prototype]]: Array(0)

I can not figure out why data is not binding and loading. I get a empty default handsontable with header rows. I thought it might be a timing issue because it says undefinded. So I read in another answer to place a ? on this line of code to make sure the data is there before trying to access it.

 let mydata = response.data?.map( data => (
                  [data.stg_st_number, data.stg_g1, data.stg_g2, data.stg_g3, data.stg_g4, data.stg_g5
                  , data.stg_g6, data.stg_g7, data.stg_g8, data.stg_g9, data.stg_g10, data.stg_final]
            ))

Possible I'm not really returning an array of arrays?

thanks in advance

handsontable.full.min.js:920 Uncaught (in promise) Error: loadData only accepts array of objects or array of arrays (undefined given) at t.replaceData (handsontable.full.min.js:920:123400) at t.default.loadData (handsontable.full.min.js:920:70714) at guestbook:75:13 I have included a small main.py program with 4 print statements to show the issue and a small html file with JavaScript

main.py

import sqlite3
import os
app = Flask(__name__)

# Connect to the SQLite database.
chk_db_path = os.environ.get('SYSTEMDRIVE') + os.environ.get('HOMEPATH') + '\\PycharmProjects\\10\\chk\\chk.db'
print('chk_db_path = ', chk_db_path)
con = sqlite3.connect(chk_db_path, check_same_thread=False)
con.row_factory = sqlite3.Row


@app.route('/guestbook')
def guestbook():
    return render_template('guestbook.html')


@app.route('/guestbook/create_entry', methods=['POST'])
def create_entry():

    print("in create")
    # get input form fields course number and section, in json format, from web page using fetch api
    req = request.get_json()
    print(req['coursenumber'], req['section'])
    # query st_grades for all students in that course number,section, semester
    sm = con.execute('''Select sm_year||sm_semester from semester where sm_status = :status''', {'status': "Active"}).fetchone()
    for current_semester in sm:
        get_crs_grade = con.execute('''SELECT * FROM st_grades WHERE stg_crs_number = :crs_number
                                             AND stg_crs_section = :crs_section
                                             AND stg_st_semester = :sm''',
                                    {'crs_number': req['coursenumber'],'crs_section': req['section'], 'sm': current_semester})
        crs_grade = get_crs_grade.fetchall()
        print('update student grades for course')
        list_comp_version = [{k: item[k] for k in item.keys()} for item in crs_grade]
        print(type(list_comp_version), list_comp_version)
        # Convert the list of dictionaries into an array of arrays.
        array_of_arrays = [[element for element in dictionary.values()] for dictionary in list_comp_version]
        print(type(array_of_arrays), array_of_arrays)

        res = make_response(jsonify(array_of_arrays), 200)
        print(type(res), res)
        # res = make_response(jsonify(req), 200)
        return res


if __name__ == '__main__':
    app.run(debug=True)


guestbook.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Guestbook</title>
    <link type="text/css" rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/[email protected]/dist/handsontable.full.min.css"/>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col">
            <h1> Instructor Grades Update</h1>
            <hr>
            <div class="mb3">
                <div class="form-group">
                    <label>Course Number</label>
                    <input type="text" class="form-control" id="coursenumber" placeholder="Enter course number">
                </div>

                <div class="form-group">
                    <label>Section</label>
                    <input type="text" class="form-control" id="section" placeholder="Enter section letter">
                </div>

                <button type="button" class="btn btn-primary"
                        style="margin-right: 30px; margin-top: 30px; margin-bottom 30px" onclick="submit_entry();">
                    Display Grades
                </button>

            </div>
        </div>
    </div>
    <div class="ht"></div>
</div>

<script>
    function submit_entry(){
        const ht = document.querySelector('.ht');
        let hot;

        var coursenumber = document.getElementById("coursenumber");
        var section = document.getElementById("section");
        var entry  = {
            coursenumber: coursenumber.value,
            section: section.value
        };

    hot = new Handsontable(ht, {
        colHeaders: ['Student Number', 'Grade 1', 'Grade 2', 'Grade 3', 'Grade 4', 'Grade 5', 'Grade 6',
          'Grade 7', 'Grade 8', 'Grade 9', 'Grade 10', 'Final Grade'],
      rowHeaders: true,
      licenseKey: 'non-commercial-and-evaluation'
    })

        fetch(`${window.origin}/guestbook/create_entry`, {
            method: "POST",
            credentials: "include",
            body: JSON.stringify(entry),
            cache: "no-cache",
            headers: new Headers({
                "content-type": "application/json"
            })
        })
        .then(function(response){
            if (response.status !== 200){
                console.log(`Response status was not 200: ${response.status}`);
                return;
            }
            response.json().then(function(data){
                console.log(data);
            let mydata = response.data?.map( data => (
                  [data.stg_st_number, data.stg_g1, data.stg_g2, data.stg_g3, data.stg_g4, data.stg_g5
                  , data.stg_g6, data.stg_g7, data.stg_g8, data.stg_g9, data.stg_g10, data.stg_final]
            ))
            hot.loadData(mydata)
            })
        })
     }
</script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
        crossorigin="anonymous"></script>
</body>
</html>
0

There are 0 best solutions below