Import CSV

Import CSV

nitinknitink Posts: 17Questions: 6Answers: 1

With reference to the question I had asked here

I have Parent table (Quiz) which has a Child table (Questions). The Questions table in turn has in-line child table Answers

I have added Import CSV to bulk import Questions. The import part works fine. However, after the import is done, I am getting following error

DataTables warning: table id=tblQuestion - Requested unknown parameter 'Id' for row 4, column 0. For more information about this error, please see http://datatables.net/tn/4

I checked the link mentioned in the error above. I could not find any solution. The number of columns defined in the HTML table and DataTable are same. I have double checked that the Id column exists in table def (line 39 in the HTML code given below) and JSON response (line 23 in the Questions DataTable code below). What am I missing here?

NOTE - I am using a questionsEditor for normal Add/Edit/Delete and a separate questionSimpleEditor for Import CSV

Here is my partial HTML code

<div class="table-responsive">
    <table id="tblQuiz" class="display responsive nowrap" style="width:100%">
        <thead>
            <tr>
                <th>Id</th>
                <th>Title</th>
                <th>Description</th>
                <th>Publish Date</th>
                <th>Expiry Date</th>
            </tr>
        </thead>
        <tbody></tbody>
        <tfoot>
            <tr>
                <th>Id</th>
                <th>Title</th>
                <th>Description</th>
                <th>Publish Date</th>
                <th>Expiry Date</th>
            </tr>
        </tfoot>
    </table>
</div>


<hr />

<h3>Questions for the selected quiz</h3>

<p>
    Find below the list of questions associated with the selected quiz. Click on the <img src="/images/details_open.png" alt="plus sign" /> to see answers
</p>

<div class="table-responsive">
    <table id="tblQuestion" class="display responsive nowrap" style="width:100%">
        <thead>
            <tr>
                <th>Answers</th>
                <th>Id</th>
                <th>Text</th>
                <th>Points</th>
            </tr>
        </thead>
        <tbody></tbody>
        <tfoot>
            <tr>
                <th>Answers</th>
                <th>Id</th>
                <th>Text</th>
                <th>Points</th>
            </tr>
        </tfoot>
    </table>
</div>

And here is the Javascript code for Questions table (I can send you the entire code if required)

var questionTable = $('#tblQuestion').DataTable({
        dom: "Bfrtip",

        serverSide: false,
        "ajax": {
            "url": "/CC/GetQuestions",
            "type": "POST",
            "datatype": "json",
            "data": function ( d ) {
                var selected = quizTable.row( { selected: true } );
                if ( selected.any() ) {
                    d.QuizId = selected.data().Id;
                }
            },
            "dataSrc": function (json) {
                return json.data;
            }
        },
        idSrc: "Id",
        order: [1, "asc"],
        columns: [

            { "data": "Id", "visible": false },
            { "data": "Text" },
            { "data": "Points" },
            {
                className: 'details-control',
                orderable: false,
                data: null,
                defaultContent: '',
                width: '10%'
            },
        ],
        select: {
            style:    'os',
            selector: 'td:not(:first-child)'
        },
        buttons: [
            { extend: "create", editor: questionsEditor },
            { extend: "edit", editor: questionsEditor },
            { extend: "remove", editor: questionsEditor },
            {
                text: 'Import Questions',
                action: function () {
                    uploadEditor.create( {
                        title: 'CSV file import'
                    } );
                }
            },
        ]
    });

Here is the CSV upload code

 // Display an Editor form that allows the user to pick the CSV data to apply to each column
    function selectColumns ( editor, csv, header) {
        var selectEditor = new $.fn.dataTable.Editor();
        var fields = editor.order();
     
        for ( var i=0 ; i<fields.length ; i++ ) {
            var field = editor.field( fields[i] );
     
            selectEditor.add( {
                label: field.label(),
                name: field.name(),
                type: 'select',
                options: header,
                def: header[i]
            } );
        }
     
        selectEditor.create({
            title: 'Map CSV fields',
            buttons: 'Import '+csv.length+' records',
            message: 'Select the CSV column you want to use the data from for each field.',
        });


        selectEditor.on('submitComplete', function (e, json, data, action) {
            // Use the host Editor instance to show a multi-row create form allowing the user to submit the data.
            editor.create(csv.length, {
                title: 'Confirm import',
                buttons: 'Submit',
                message: 'Click the <i>Submit</i> button to confirm the import of ' + csv.length + ' rows of data. Optionally, override the value for a field to set a common value by clicking on the field below.'
            });

            for (var i = 0; i < fields.length; i++) {
                var field = editor.field(fields[i]);
                var mapped = data[field.name()];

                for (var j = 0; j < csv.length; j++) {
                    field.multiSet(j, csv[j][mapped]);
                }
            }
        });
    }

    questionSimpleEditor = new $.fn.dataTable.Editor( {
        ajax: "/CC/ImportQuestionAndAnswers",
        table: "#tblQuestion",
        fields: [

            {
                label: "Question Text:",
                name: "Text"
            },
            {
                label: "Question Points:",
                name: "Points"
            },
            {
                label: "Ans 1 Text:",
                name: "Ans1_Text"
            },
            {
                label: "Ans 1 Is Right Answer:",
                name: "Ans1_IsRightAnswer"
            },
            {
                label: "Ans 2 Text:",
                name: "Ans2_Text"
            },
            {
                label: "Ans 2 Is Right Answer:",
                name: "Ans2_IsRightAnswer"
            },
            {
                label: "Ans 3 Text:",
                name: "Ans3_Text"
            },
            {
                label: "Ans 3 Is Right Answer:",
                name: "Ans3_IsRightAnswer"
            },
            {
                label: "Ans 4 Text:",
                name: "Ans4_Text"
            },
            {
                label: "Ans 4 Is Right Answer:",
                name: "Ans4_IsRightAnswer"
            }
        ]
    });

    questionSimpleEditor.on('initSubmit', function (e, action) {
        return new Promise(function (resolve) {
            var quizId22 = quizTable.row({ selected: true }).data().Id;
            questionSimpleEditor.add( {
                name: "quizId",
                type: "hidden",
            }, null);

            questionSimpleEditor.val('quizId', quizId22);
            resolve("");
        });
    });

    // Upload Editor - triggered from the import button. Used only for uploading a file to the browser
    var uploadEditor = new $.fn.dataTable.Editor( {
        fields: [ {
            label: 'CSV file:',
            name: 'csv',
            type: 'upload',
            ajax: function ( files ) {
                // Ajax override of the upload so we can handle the file locally. Here we use Papa
                // to parse the CSV.
                Papa.parse(files[0], {
                    header: true,
                    skipEmptyLines: true,
                    complete: function (results) {
                        if ( results.errors.length ) {
                            console.log( results );
                            uploadEditor.field('csv').error( 'CSV parsing error: '+ results.errors[0].message );
                        }
                        else {
                            uploadEditor.close();
                            selectColumns( questionSimpleEditor, results.data, results.meta.fields);
                        }
                    }
                });
            }
        } ]
    });


This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    table id=tblQuestion - Requested unknown parameter 'Id' for row 4, column 0.

    Did you validate the actual JSON response in the developer tools?

    Take a look at all the rows, especially row 4 to make sure it has an Id object. You can paste the response here if you want us to take a look.

    Kevin

  • nitinknitink Posts: 17Questions: 6Answers: 1

    Hello,

    Please find below the JSON response from the server. Also where are the developer tools? Or do you mean the ones in Chrome?

    {
      "data": [
        [
          {
            "MediaFileType": null,
            "MediaFileId": null,
            "AnswerType": "Single Choice",
            "Text": "NFL Team in Dallas",
            "Points": 10,
            "IsTextOnly": true,
            "AnswerTypeId": 10,
            "QuizId": 10,
            "Quiz": null,
            "Answers": [
              {
                "Text": "Redskins",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 30,
                "Question": null,
                "Id": 57,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:52.713156Z"
              },
              {
                "Text": "Cowboys",
                "IsRightAnswer": true,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 30,
                "Question": null,
                "Id": 58,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:52.713156Z"
              },
              {
                "Text": "Patriots",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 30,
                "Question": null,
                "Id": 59,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:52.713156Z"
              },
              {
                "Text": "Colts",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 30,
                "Question": null,
                "Id": 60,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:52.713156Z"
              }
            ],
            "QuestionMedias": [],
            "GuestCodes": [],
            "Tags": [],
            "Id": 30,
            "IsActive": true,
            "UpdateUser": "",
            "UpdateDate": "2019-09-20T18:56:52.713155Z"
          },
          {
            "MediaFileType": null,
            "MediaFileId": null,
            "AnswerType": "Multi Choice",
            "Text": "Which of these are leap years?",
            "Points": 10,
            "IsTextOnly": true,
            "AnswerTypeId": 20,
            "QuizId": 10,
            "Quiz": null,
            "Answers": [
              {
                "Text": "2020",
                "IsRightAnswer": true,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 31,
                "Question": null,
                "Id": 61,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:53.074986Z"
              },
              {
                "Text": "2026",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 31,
                "Question": null,
                "Id": 62,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:53.074986Z"
              },
              {
                "Text": "2018",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 31,
                "Question": null,
                "Id": 63,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:53.074986Z"
              },
              {
                "Text": "2028",
                "IsRightAnswer": true,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 31,
                "Question": null,
                "Id": 64,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:53.074986Z"
              }
            ],
            "QuestionMedias": [],
            "GuestCodes": [],
            "Tags": [],
            "Id": 31,
            "IsActive": true,
            "UpdateUser": "",
            "UpdateDate": "2019-09-20T18:56:53.074985Z"
          }
        ]
      ],
      "error": null
    }
    
    
  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736
    Answer ✓

    Also where are the developer tools? Or do you mean the ones in Chrome?

    Yes, in Chrome.

    The other thing to do is in the ajax.dataSrc function use console.log(json.data); so you can see exactly what Datatables will process:

    var questionTable = $('#tblQuestion').DataTable({
            dom: "Bfrtip",
     
            serverSide: false,
            "ajax": {
                "url": "/CC/GetQuestions",
                "type": "POST",
                "datatype": "json",
                "data": function ( d ) {
                    var selected = quizTable.row( { selected: true } );
                    if ( selected.any() ) {
                        d.QuizId = selected.data().Id;
                    }
                },
                "dataSrc": function (json) {
                    console.log(json.data);
                    return json.data;
                }
            },
    

    I'm a bit confused by the json response you show versus the Datatable config:

    {
      "data": [
        [
          {
            "MediaFileType": null,
            "MediaFileId": null,
            "AnswerType": "Single Choice",
            "Text": "NFL Team in Dallas",
            "Points": 10,
            "IsTextOnly": true,
            "AnswerTypeId": 10,
            "QuizId": 10,
            "Quiz": null,
            "Answers": [
              {
                "Text": "Redskins",
                "IsRightAnswer": false,
                "SortOrder": 0,
                "ShowRandom": false,
                "QuestionId": 30,
                "Question": null,
                "Id": 57,
                "IsActive": true,
                "UpdateUser": "",
                "UpdateDate": "2019-09-20T18:56:52.713156Z"
              },
    ...
    

    The data object looks like it is an array containing an array of items. This doesn't seem to match up to the return json.data;. Take a closer look to make sure what is being returned matches what you are returning in the ajax.dataSrc.

    Kevin

  • nitinknitink Posts: 17Questions: 6Answers: 1

    Thanks you so much. The issue was incorrect JSON response from the server. I fixed it and it's working properly now.

    Once again - Thank You

This discussion has been closed.