Examples of DataTables implementation using Flask-Mongoengine?

Examples of DataTables implementation using Flask-Mongoengine?

plangevinplangevin Posts: 16Questions: 1Answers: 0

Has anyone ever implemented DataTables using flask-mongoengine? Trying to get the Ajax to work, but get an error message on the JSON format or a more general error. Would like to see an example using mongoengine to diagnose my problem.

Thanks in advance for such an example.

Answers

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    I've no experience of that, but this thread may help, the chap seemed happy at the end,

    Colin

  • kthorngrenkthorngren Posts: 21,322Questions: 26Answers: 4,948
    edited February 2022

    See this SO thread about returning JSON data in Flask. I used Flask, but not flask-mongoengine, for one of my Datatable projects and just return the dictionary as shown in the SO thread.

    What do you see in the browser's network inspector?

    Have you used a site like https://jsonlint.com/ to validate the JSON?

    Kevin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0
    edited February 2022

    Actually, my question may not be linked to mongoengine, but just Flask itselfl, as I am able to get this JSON out of my Ajax URL, when I call it directly. This is the JSON I am getting, but it still does not allow me to get the DataTables populated. I get the following error message when I call it from my Javascript. A JSON parser, like the one above (https://jsonlint.com/) tells me that my JSON is valid, at least from a formatting point of view. My code will follow in the next post to avoid an overwhelming comment.

    DataTables warning: table id=data - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

    {
        "data": [{
            "admin": true,
            "confirmed": true,
            "confirmed_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "email": "aaa@aaaa.com",
            "language": "en",
            "num_id": 1,
            "registered_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "superadmin": true,
            "username": "patrick",
            "usfr_id": "USR-1"
        }, {
            "admin": true,
            "confirmed": true,
            "confirmed_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "email": "aaa@aaaa.com",
            "language": "fr",
            "num_id": 3,
            "registered_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "superadmin": true,
            "username": "pierre",
            "usfr_id": "USR-2"
        }, {
            "admin": true,
            "confirmed": true,
            "confirmed_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "email": "aaa@aaaa.com",
            "language": "fr",
            "num_id": 5,
            "registered_on": "Tue, 01 Feb 2022 15:11:57 GMT",
            "superadmin": true,
            "username": "nicole",
            "usfr_id": "USR-3"
        }],
        "draw": 1,
        "recordsFiltered": 10,
        "recordsTotal": 100
    }
    

    Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

  • plangevinplangevin Posts: 16Questions: 1Answers: 0
    edited February 2022

    My route:

    @user.route('/api/data', methods=['POST'])
    def data():
        total_filtered = 10
    
        # sorting
        order = []
        i = 0
        while True:
            col_index = request.args.get(f'order[{i}][column]')
            if col_index is None:
                break
            col_name = request.args.get(f'columns[{col_index}][data]')
            if col_name not in ['username', 'age', 'email']:
                col_name = 'username'
            descending = request.args.get(f'order[{i}][dir]') == 'desc'
            col = getattr(User, col_name)
            if descending:
                col = col.desc()
            order.append(col)
            i += 1
    
        # Set the pagination configuration
        page = request.args.get('page', 1, type=int)
        start = request.args.get('start', 1, type=int)
        length = request.args.get('length', 5, type=int)
        pagination = User.objects.paginate(page=start, per_page=length)
        data = {
            'data': [user.to_dict() for user in pagination.items],
            'recordsFiltered': 10,
            'recordsTotal': 100,
            'draw': 1
        }
        return data
    

    Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

  • plangevinplangevin Posts: 16Questions: 1Answers: 0
    edited February 2022

    My JS:

      <script>
        $(document).ready(function () {
          $('#data').DataTable({
            ajax: [{
                url: '{{ url_for('user.data') }}',
                dataSrc : ''
            }],
            serverSide: true,
            columns: [
                {data: 'usfr_id'},
                {data: 'username'},
                {data: 'email'},
                {data: 'language'},
                {data: 'registered_on'},
                {data: 'confirmed_on'},
                {data: 'confirmed', orderable: false},
                {data: 'admin', orderable: false},
                {data: 'superadmin', orderable: false}
            ],
          });
        });
      </script>
    

    Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    BTW: this is just a portion of the code for which I have hard coded values, to at least get the tables to work, which is still not the case

  • kthorngrenkthorngren Posts: 21,322Questions: 26Answers: 4,948

    Everything looks correct except you will want to remove the dataSrc : ''. Since you are returning the row data in the default data object then ajax.dataSrc doesn't need to be defined. See if this change helps and let us know.

    Kevin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0
    edited February 2022

    Thanks @kthorngren. Actually, I added this line after reading on Stack Overflow, but it did not change anything. The behaviour was the same.

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    Thanks @Colin. Will take a look

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    Still not working. I am validating the JSON with the validator and I am told it's a valid JSON. What could go wrong? When I go to inspect the page, I am not seing the JSON in the response. But, I do see the payload in the payload tab.

  • kthorngrenkthorngren Posts: 21,322Questions: 26Answers: 4,948

    I am not seing the JSON in the response.

    That is the problem. Guess I made the assumption that the JSON your were validating was from the network inspector. You will need to debug your Flask app to see why its return data is not returning JSON in the response.

    Kevin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    The JSON above is what I get when I comment out my code associated to the GET method and then change my AJAX URL to handle both GET and POST. In this case, I get the very JSON that you see above. So, I know that my return data gives JSON. However, it does not seem to be passed on to the web page itself. When I take the output and copy it into any JSON validator, I get "VALID JSON". But, when I revert back to handling only POST within my Flask code and un-comment the method handling the GET method, then it give me the error message that JSON is not valid.

    The method I am referring for the GET method only renders a template "/user/users.html". Nothing more. The POST has the code that generates the JSON.

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    What I see in the Response tab of the network inspector is this:

    It only gives me pure HTML, with the code of the web page itself.

  • kthorngrenkthorngren Posts: 21,322Questions: 26Answers: 4,948

    If you want to send a POST request then you will need to add "type": "POST" to the ajax option. Like this:

          ajax: [{
              url: '{{ url_for('user.data') }}',
              type : 'POST'
          }],
    

    However, it does not seem to be passed on to the web page itself

    If you don't see the JSON in the response tab of the browser's network inspector then the issue with sending the response.

    Kevin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    I tried using a random path and it gave me the same behaviour. I am new to using AJAX, so here is my code:

    And the Flask code. What path should I call?

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    I tried adding type : 'POST' and it did not work, but the more I am thinking, the more I am thinking it is the path that is wrong.

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    Thanks a lot Kevin by the way. You're effort to help is very much appreciated

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    I also tried with url_for("user.ajaxdatatable")

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Are you seeing errors in the console? That might give clues.

    Colin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    I am not seeing errors in the console, other than with a datepicker function, which is likely not related. Other than that, no errors

  • kthorngrenkthorngren Posts: 21,322Questions: 26Answers: 4,948

    If I understand correctly you have this configuration:

    ajax: [{
        url: '{{ url_for('user.data') }}',
        type : 'POST'
    }],
    

    Flask is generating a URL for the template. Use the browsers's view source option to see what URL is generated. Is the URL correct?

    url: '{{ url_for('user.data') }}',
    

    This doesn't look correct. I think the outer quotes should be double quotes, like this:

    url: "{{ url_for('user.data') }}",
    

    As a test hard code the correct URL like this:

    ajax: [{
        url: 'path/api/data',
        type : 'POST'
    }],
    

    You are saying that you don't see anything in the Ajax response using the browser tools. This isn't caused by Datatables nor the browser. Its something with the Flask app. Could be going to the wrong route. What is the response status code?

    Have you debugged the Flask app to make sure the correct route is used and the response is correct?

    You can use a tool like postman to test your Flask app outside of the web browser and Datatables.

    Kevin

  • plangevinplangevin Posts: 16Questions: 1Answers: 0

    Thanks Kevin. Will test all this. BTW, believe me, I'm not even thinking in any ways that DataTables is responsible for any of this :-). LOL. I appreciate the hints

Sign In or Register to comment.