Data Not Processed On Edit In Node

Data Not Processed On Edit In Node

daduffydaduffy Posts: 31Questions: 5Answers: 1

I have a Node datatables editor project setup. I can create records, however, I cannot edit records.

The data is passed into Node, I have set the urlencode to true, but It doesn't appear that anything happens.

I am using versions:
Datatables 1.10.19
DataTables Editor v1.9.0

Here is the section of my code for debug:

  let editor = new Editor( edb, 'tbl_company', 'companyid' ).fields(
    new Field( 'company' ),
    new Field( 'address1' ),
    new Field( 'address2' ),
    new Field( 'city' ),
    new Field( 'province' ),
    new Field( 'postal' ),
    new Field( 'country' ),
    new Field( 'officephone' ),
    new Field( 'faxphone' ),
    new Field( 'creationdate' )
            .validator(
                Validate.dateFormat(
                    'YYYY-MM-DD',
                    null,
                    new Validate.Options({
                        message: 'Please enter a date in the format yyyy-mm-dd'
                    })
                )
            )
            .getFormatter(Format.sqlDateToFormat('YYYY-MM-DD'))
            .setFormatter(Format.formatToSqlDate('YYYY-MM-DD')),
    new Field( 'notes' ),
    new Field( 'hide' )
  );

  console.log( 'req.body:' ) ;
  console.log( req.body ) ;
  
  await editor.process( req.body ) ;
  
  console.log( 'editor.data():' ) ;
  console.log( editor.data() ) ;

Those two console logs produce:

req.body:
{ action: 'edit',
  data:
   [ { companyid: '15',
       company: 'ABC Corp',
       address1: '123 Fake Street',
       address2: '',
       city: 'Somewhere',
       province: 'ON',
       postal: 'A1B2C3',
       country: 'Canada',
       officephone: '7058675309',
       faxphone: '',
       creationdate: '',
       notes: '',
       hide: '1' } ] }
editor.data():
{ data: [], fieldErrors: [] }

Any direction that anyone can provide would be greatly appreciated.

Dave

This question has accepted answers - jump to:

Answers

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    I forgot the link to the test https://salto.as5.co/db/company

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

    Hi @daduffy ,

    The data in the console log above is making it back to the Editor client - it's being sent:

    {"data":[],"fieldErrors":[]}
    

    It should be receiving the modified data back from the server. After your editor.process(), I think you have to send the data back to the server with:

    res.json(editor.data());
    

    Hope that does the trick,

    Cheers,

    Colin

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    Hey @colin ,

    Thanks for the reply. I am sending it back that way with the res.json, I was just trying to post the part of my code where I thought the problem was, I truncated the paste too early. Sorry about that.

    The issue appears to be in the editor.process.

    If I create a record, everything looks good, however, nothing happens on an edit. I put a link to the project in the previous link if that helps at all.

    Dave

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    Hi Dave,

    In your Knex configuration could you add debug: true so we can see what SQL is being generated please? It will dump it out onto the console (assuming you are running your script from there).

    Also add editor.tryCatch(false); before the process call. I've got a feeling that there is an SQL error happening and the error is being thrown away.

    Thanks,
    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    Well, I thought it was an SQL issue too, and it does appear to be that the query is where we are breaking.

    ComQueryPacket {
      command: 3,
      sql:
       'update `tbl_company` set `company` = \'Dave\', `address1` = \'555 Main\', `address2` = \'\', `city` = \'Sudbury\', `province` = \'ON\', `postal` = \'A1B2C3\', `country` = \'Canada\', `officephone` = \'7058675309\', `faxphone` = \'\', `creationdate` = \'Invalid date\', `notes` = \'\', `hide` = 0 where `companyid` = \'0\'' }
    

    All of the data is escaped, I don't know if that is a problem or not. In any event, the id is not 0. I don't know where that is coming from.

    Here is my editor server script

    router.all('/company', async function(req, res) {
      let editor = new Editor( edb, 'tbl_company', 'companyid' ).fields(
        new Field( 'company' ),
        new Field( 'address1' ),
        new Field( 'address2' ),
        new Field( 'city' ),
        new Field( 'province' ),
        new Field( 'postal' ),
        new Field( 'country' ),
        new Field( 'officephone' ),
        new Field( 'faxphone' ),
        new Field( 'creationdate' )
                .validator(
                    Validate.dateFormat(
                        'YYYY-MM-DD',
                        null,
                        new Validate.Options({
                            message: 'Please enter a date in the format yyyy-mm-dd'
                        })
                    )
                )
                .getFormatter(Format.sqlDateToFormat('YYYY-MM-DD'))
                .setFormatter(Format.formatToSqlDate('YYYY-MM-DD')),
        new Field( 'notes' ),
        new Field( 'hide' )
      );
    
      var i, f, numericFields = [ 'companyid', 'hide' ] ;
      for( i in req.body.data ) {
        for( f in numericFields ) {
          req.body.data[ i ][ numericFields[ f ] ] = parseInt( req.body.data[ i ][ numericFields[ f ] ] ) ;
          //req.body.data[ i ].companyid = parseInt( req.body.data[ i ][ numericFields[ f ] ] ) ;
        }
      }
      
      // console.log( 'editor:' ) ;
      // console.log( editor ) ;
      
      // console.log( 'req.body' ) ;
      // console.log( req.body ) ;
      
      editor.tryCatch(false);
      await editor.process( req.body ) ;
      
      // console.log( 'editor' ) ;
      // console.log( editor ) ;
      res.json( editor.data() );
    } );
    

    Let me know if there is anything else you need.

    Thanks again for all of your help.

    Dave

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    So, I am not sure that the server is picking up the rowid. From console dumps, all of the data is passed, if I dump
    the editor object, it has brought in the formdata just fine.

    The editor object recognizes that the pkey is companyid. I have messed around with changing the idprefix to something different, nothing, and default, and that doesn't appear to help. I have changed it both on the client and server sides.

    It is almost as if the process of changing the bodyparser so that the object can be read eliminates the rowid dats. I think this because it works just fine on an insert, and that is the only real difference I see in the recieved data when I compare my node server script to my php server script.

    Am I off, or could I be on the right track?

    Dave

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    Hi Dave,

    I think you are right - I missed that in the original JSON that shows your req.body. It doesn't have an id for the row, which it really should. So a few things:

    1. Can you show me your client-side Javascript for Editor please?
    2. Can you show me the HTTP parameters that Editor is sending to the server on edit ("Headers" section of the XHR in your browser's Network inspector).

    Thanks,
    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    I use the same table throughout my project and call a routine to define the tableDef object that you see below... I just did a dump of what it is producing so that you can see how the editor and table are defined. I changed a couple of details so as not to expose everything in this post for all to see forever. :)

    Request Headers

    :authority: [I REMOVED THIS DETAIL]
    :method: POST
    :path: /dte/company
    :scheme: https
    accept: application/json, text/javascript, */*; q=0.01
    accept-encoding: gzip, deflate, br
    accept-language: en-US,en;q=0.9
    content-length: 424
    content-type: application/x-www-form-urlencoded; charset=UTF-8
    cookie: __cfduid=d36b47fdd728edfa95951ba0b914ae05a1558730067; _fbp=fb.1.1558730076968.310742823
    origin: https://[I REMOVED THIS DETAIL]
    referer: https://[I REMOVED THIS DETAIL]/db/company
    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
    x-requested-with: XMLHttpRequest
    

    Response Headers

    cf-ray: 4ed7f5b2ce6cca9c-YYZ
    content-length: 39
    content-type: application/json; charset=utf-8
    date: Thu, 27 Jun 2019 14:02:38 GMT
    etag: W/"27-Cw+8uIyk3io264blw97vyo6U3Ho"
    expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
    server: cloudflare
    status: 200
    x-content-type-options: nosniff
    x-powered-by: Express
    x-server-powered-by: Engintron
    x-xss-protection: 1; mode=block
    

    Thought I'd throw in the form data for good measure

    action=edit&data%5B14%5D%5Bcompanyid%5D=14&data%5B14%5D%5Bcompany%5D=Dave&data%5B14%5D%5Baddress1%5D=555+Main&data%5B14%5D%5Baddress2%5D=&data%5B14%5D%5Bcity%5D=Sudbury&data%5B14%5D%5Bprovince%5D=ON&data%5B14%5D%5Bpostal%5D=A1B2C3&data%5B14%5D%5Bcountry%5D=Canada&data%5B14%5D%5Bofficephone%5D=7058675309&data%5B14%5D%5Bfaxphone%5D=&data%5B14%5D%5Bcreationdate%5D=2019-06-19&data%5B14%5D%5Bnotes%5D=&data%5B14%5D%5Bhide%5D=0
    
    tableDef = {
      "idSrc": "companyid",
      "fields": [
        {
          "label": "ID",
          "name": "companyid",
          "type": "hidden"
        },
        {
          "label": "Company",
          "name": "company"
        },
        {
          "label": "Address",
          "name": "address1"
        },
        {
          "label": "Line 2",
          "name": "address2"
        },
        {
          "label": "City",
          "name": "city"
        },
        {
          "label": "Province",
          "name": "province"
        },
        {
          "label": "Postal",
          "name": "postal"
        },
        {
          "label": "Country",
          "name": "country"
        },
        {
          "label": "Phone",
          "name": "officephone"
        },
        {
          "label": "Fax",
          "name": "faxphone"
        },
        {
          "label": "Start Date",
          "name": "creationdate",
          "type": "date",
          "def": "2019-06-27"
        },
        {
          "label": "Notes",
          "name": "notes"
        },
        {
          "label": "Deleted",
          "name": "hide",
          "type": "radio",
          "options": [
            {
              "label": "No",
              "value": 0
            },
            {
              "label": "Yes",
              "value": 1
            }
          ],
          "def": 0
        }
      ],
      "columns": [
        {
          "data": "company",
          "mData": "company"
        },
        {
          "data": "address1",
          "mData": "address1"
        },
        {
          "data": "address2",
          "mData": "address2"
        },
        {
          "data": "city",
          "mData": "city"
        },
        {
          "data": "province",
          "mData": "province"
        },
        {
          "data": "postal",
          "mData": "postal"
        },
        {
          "data": "country",
          "mData": "country"
        },
        {
          "data": "officephone",
          "mData": "officephone"
        },
        {
          "data": "faxphone",
          "mData": "faxphone"
        },
        {
          "data": "creationdate",
          "mData": "creationdate"
        },
        {
          "data": "notes",
          "mData": "notes"
        },
        {
          "data": "hide",
          "mData": "hide"
        }
      ],
      "columnDefs": [
        {
          "targets": [
            0
          ],
          "title": "Company",
          "className": "text-center",
          "name": "company",
          "orderable": true,
          "bSortable": true,
          "sTitle": "Company",
          "sName": "company",
          "sClass": "text-center"
        },
        {
          "targets": [
            1
          ],
          "title": "Address",
          "className": "text-center",
          "name": "address1",
          "orderable": true,
          "bSortable": true,
          "sTitle": "Address",
          "sName": "address1",
          "sClass": "text-center"
        },
        {
          "targets": [
            2
          ],
          "title": "Line 2",
          "className": "text-center",
          "name": "address2",
          "orderable": false,
          "bSortable": false,
          "sTitle": "Line 2",
          "sName": "address2",
          "sClass": "text-center"
        },
        {
          "targets": [
            3
          ],
          "title": "City",
          "className": "text-center",
          "name": "city",
          "visible": true,
          "sTitle": "City",
          "sName": "city",
          "bVisible": true,
          "sClass": "text-center"
        },
        {
          "targets": [
            4
          ],
          "title": "Province",
          "className": "text-center",
          "name": "province",
          "visible": false,
          "sTitle": "Province",
          "sName": "province",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            5
          ],
          "title": "Postal",
          "className": "text-center",
          "name": "postal",
          "visible": false,
          "sTitle": "Postal",
          "sName": "postal",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            6
          ],
          "title": "Country",
          "className": "text-center",
          "name": "country",
          "visible": false,
          "sTitle": "Country",
          "sName": "country",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            7
          ],
          "title": "Phone",
          "className": "text-center",
          "name": "officephone",
          "visible": true,
          "sTitle": "Phone",
          "sName": "officephone",
          "bVisible": true,
          "sClass": "text-center"
        },
        {
          "targets": [
            8
          ],
          "title": "Fax",
          "className": "text-center",
          "name": "faxphone",
          "visible": false,
          "sTitle": "Fax",
          "sName": "faxphone",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            9
          ],
          "title": "Start Date",
          "className": "text-center",
          "name": "creationdate",
          "visible": false,
          "sTitle": "Start Date",
          "sName": "creationdate",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            10
          ],
          "title": "Notes",
          "className": "text-center",
          "name": "notes",
          "visible": false,
          "sTitle": "Notes",
          "sName": "notes",
          "bVisible": false,
          "sClass": "text-center"
        },
        {
          "targets": [
            11
          ],
          "title": "Hide",
          "className": "text-center",
          "name": "hide",
          "visible": false,
          "sTitle": "Hide",
          "sName": "hide",
          "bVisible": false,
          "sClass": "text-center"
        }
      ]
    }
    
        buttons = [
        { extend: "edit",   editor: editor },
        {
          text: '<i title="Delete"  class="fa fa-times"></i>',
          action: function ( e, dt, node, config ) {
            
                var rows = table.rows( {selected: true} ).indexes();
            
                editor
                    .hide( editor.fields() )
                    .on( 'close', function () {
                        setTimeout( function () { // Wait for animation
                            editor.show( editor.fields() );
                        }, 500 );
                    } )
                    .edit( rows, {
                        title: 'Delete',
                            message: rows.length === 1 ?
                            'Are you sure you wish to delete this ' + dt.row( rows ).data()[ 'company' ] + '?' :
                            'Are you sure you wish to delete these '+ rows.length + ' items?',
                        buttons: 'Delete' 
                          } )
                    .val( 'hide', 1 ) ;
          }
        },
        {
          text: '<i title="New"  class="fa fa-plus"></i>',
          action: function ( e, dt, node, config ) {
            editor.create( {
              title: 'New',
              buttons: 'Save'
            } ) ;
          }
        }
      ] ;
    
    
      editor = new $.fn.dataTable.Editor( {
        ajax: '/dte/company',
        table: '#table',
        idSrc: tableDef.idSrc,
        fields: tableDef.fields
      } ) ;
    
        table = $('#tblhestia').DataTable({
            fixedHeader: {
                header: true,
                footer: false
            },
        "dom": 'Bifr<"contactstoolbar">t',
            "pageLength": -1,
        select: {
            'style': 'multi'
        },
        "fnCreatedRow": function( nRow, aData, iDataIndex ) {
          $(nRow).attr('id', 'row_' + aData[ tableDef.idSrc ] ) ;
        },
        "language": {
          "emptyTable": "Retrieving Data <i class='fa fa-circle-o-notch fa-spin'></i>",
          "loadingRecords": "Retrieving Data <i class='fa fa-circle-o-notch fa-spin'></i>"//,
        },
            buttons: buttons,
            responsive: true,
        "ajax": {
          'url': '/db/company?r=raw' ,
          'type': 'GET',
          'data': {
            f: 'r',
                    'w': 'c'
          }
        },
        columns: tableDef.columns,
            "columnDefs": tableDef.columnDefs,
            'order': [[1, 'asc']],
        colReorder: true,
        stateSave:  true
        });
    
  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    Also @allan is the donate button the best way to send some sheckles to you for all of your help?

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    :). You've got an Editor license - that's plenty enough thanks!

    This is what the client is sending to the server:

    action=edit
    data[14][companyid]=14
    data[14][company]=Dave
    data[14][address1]=555+Main
    data[14][address2]=
    data[14][city]=Sudbury
    data[14][province]=ON
    data[14][postal]=A1B2C3
    data[14][country]=Canada
    data[14][officephone]=7058675309
    data[14][faxphone]=
    data[14][creationdate]=2019-06-19
    data[14][notes]=
    data[14][hide]=0
    

    So the question becomes, why is that 14 being dropped?

    How are you setting up body-parser? In the demos (Express) I use:

    app.use( bodyParser.urlencoded({ extended: true }) );
    

    Thanks,
    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    I am using it directly in Express, from the docs it looks like that is the future of things. I will add the other library and try it that way.

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    Alas, that didn't do the trick. Everything is as before. Of note: when I dump the post data on the server side is that I cannot find the row id anywhere. The data object doesn't mention it, sort of like the act of parsing it with extended removes that reference to the data's key.

    Is there a workaround that might work? I can look through the code, but is there a routine that I can call that will allow me to set the row id manually?

    Thanks again for all that you guys do!

    Dave

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    What version of body parser are you using? I don't know of a workaround for this I'm afraid, as I don't recall having seen something quite like this before. The client-side is sending the correct data to the server, but the server-side isn't parsing it correctly.

    Can you also show me your full server-side Javascript?

    Thanks,
    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    I installed version 1.19.0 of body parser.

    Here is my app.js file:

    var createError = require('http-errors') ;
    var express = require('express') ;
    var bodyParser = require('body-parser') ;
    var path = require('path');
    var cookieParser = require('cookie-parser') ;
    var logger = require('morgan') ;
    var uuid = require('uuid/v4') ;
    var session = require('express-session') ;
    var FileStore = require('session-file-store')(session);
    var passport = require('passport');
    var LocalStrategy = require('passport-local').Strategy;
    
    var indexRouter = require('./routes/index');
    var usersRouter = require('./routes/users');
    var dbRouter = require('./routes/db');
    var datatablesEditor = require('./routes/editor');
    var loginRouter = require('./routes/login');
    
    //change to read from DB
    const users = [
      {id: '2f24vvg', username: 'hello', password: 'world'}
    ] ;
    
    // configure passport.js to use the local strategy
    passport.use(new LocalStrategy(
      { usernameField: 'username' },
      ( username, password, done ) => {
        console.log( 'Inside local strategy callback' ) ;
        // here is where you make a call to the database
        // to find the user based on their username or email address
        // for now, we'll just pretend we found that it was users[0]
        const user = users[ 0 ] ;
        if( username === user.username && password === user.password ) {
          console.log( 'Local strategy returned true' ) ;
          return done( null, user ) ;
        }
      }
    ));
    
    // tell passport how to serialize the user
    passport.serializeUser((user, done) => {
      console.log( 'Inside serializeUser callback. User id is save to the session file store here' ) ;
      done( null, user.id ) ;
    });
    
    var app = express();
    
    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');
    
    app.use(logger('dev'));
    //app.use(express.json());
    //app.use(express.urlencoded({ extended: true }));
    app.use(bodyParser.json());
    app.use( bodyParser.urlencoded({ extended: true }) );
    
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    // add & configure middleware
    app.use(session({
      genid: (req) => {
        //console.log( 'session middleware session id' ) ;
        //console.log( req.sessionID ) ;
        return uuid() ; // use UUIDs for session IDs
      },
      store: new FileStore(),
      secret: 'keyboard cat',
      resave: false,
      saveUninitialized: true
    } ) ) ;
    
    app.use(passport.initialize());
    app.use(passport.session());
    
    app.use( '/', indexRouter ) ;
    app.use( '/users', usersRouter ) ;
    app.use( '/db', dbRouter ) ;
    app.use( '/dte', datatablesEditor ) ;
    app.use( '/login', loginRouter ) ;
    
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      next(createError(404));
    });
    
    // error handler
    app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
    
      // render the error page
      res.status(err.status || 500);
      res.render('error');
    });
    
    module.exports = app;
    

    Here is my editor.js file:

    var express = require('express');
    var router = express.Router();
    
    let edb = require('./edb');
    
    let {
        Editor,
        Field,
        Validate,
        Format,
        Options,
        Mjoin
    } = require("datatables.net-editor-server");
    
    router.all('/company', async function(req, res) {
      let editor = new Editor( edb, 'tbl_company', 'companyid' )
        .idPrefix( '' )
        .fields(
          new Field( 'company' ),
          new Field( 'address1' ),
          new Field( 'address2' ),
          new Field( 'city' ),
          new Field( 'province' ),
          new Field( 'postal' ),
          new Field( 'country' ),
          new Field( 'officephone' ),
          new Field( 'faxphone' ),
          new Field( 'creationdate' )
                .validator(
                    Validate.dateFormat(
                        'YYYY-MM-DD',
                        null,
                        new Validate.Options({
                            message: 'Please enter a date in the format yyyy-mm-dd'
                        })
                    )
                )
                .getFormatter(Format.sqlDateToFormat('YYYY-MM-DD'))
                .setFormatter(Format.formatToSqlDate('YYYY-MM-DD')),
          new Field( 'notes' ),
          new Field( 'hide' )
        )
        .on( 'preEdit', (editor, id, values) => {
          console.log( 'editor' ) ;
          console.log( editor ) ;
          console.log( 'id' ) ;
          console.log( id ) ;
          console.log( 'values' ) ;
          console.log( values ) ;
          // editor
          //   .field( 'last_updated' )
          //   .setValue( new Date().toISOString() );
        } );
      // editor.where( 'companyid', 14 );
      
      var i, f, numericFields = [ 'companyid', 'hide' ] ;
      for( i in req.body.data ) {
        for( f in numericFields ) {
          req.body.data[ i ][ numericFields[ f ] ] = parseInt( req.body.data[ i ][ numericFields[ f ] ] ) ;
        }
      }
      editor.tryCatch(true);
      editor.debug(true);
      // console.log( 'editor:' ) ;
      // console.log( editor ) ;
      
      // console.log( 'req.body' ) ;
      // console.log( req.body ) ;
      
      // console.log( 'editor._pkey' ) ;
      // console.log( editor._pkey ) ;
      
      await editor.tryCatch(false);
      await editor.process( req.body ) ;
      
      // console.log( 'editor_post:' ) ;
      // console.log( editor ) ;
      
      res.json( editor.data() );
    } );
    
    module.exports = router;
    

    Here is my knex db file, edb.js:

    let knex = require('knex');
    var config = require('.././config');
     
    module.exports = knex({
      client: 'mysql', // pg, mssql, etc
    
      connection: {
        database:    config.dbConfig.database,
        host:        config.dbConfig.host,
        password:    config.dbConfig.password,
        user:        config.dbConfig.user,
        dateStrings: true,
        debug: true
      }
    });
    

    Let me know if there is something else you need.

    Thanks again!
    Dave

  • daduffydaduffy Posts: 31Questions: 5Answers: 1
    edited July 2019

    @allan

    Also, I should add this is the dump from calling at preEdit:

    id
    0
    values
    { companyid: 14,
      company: 'Dave',
      address1: '555 Main',
      address2: '',
      city: 'Sudbury',
      province: 'ON',
      postal: 'A1B2C3',
      country: 'Canada',
      officephone: '7058675309',
      faxphone: '',
      creationdate: '2019-07-02',
      notes: '',
      hide: 0 }
    

    I don't know if that helps narrow it down, but that is where I am at with troubleshooting.

    Dave

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    Hey @allan @colin

    Please don't misunderstand, I really appreciate all of the help you provide.

    Can I buy some support credits to get through this issue faster? I know that you said my purchase of Editor is enough, but I also know that nobody can work for free. :smile: Again, please don't take this as me being at all ungrateful for the piles of help already.

    How would be the best way to go about this?

    Thanks!
    Dave

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    Interesting - I'm not seeing anything immediately that would cause this issue. You are modifying req.body which is setting of my spiddy-senses, but it looks like it should work okay (I'd prefer for ... of ... rather than in though).

    Could you add:

    console.log('request body', req.body);
    

    at the very top of the route handler, and also again just before the process() method call, and then show me the output from the console?

    Thanks,
    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    You didn't answer my question about support credits. :wink:

    Here is the output from the top of the route:

    request body { action: 'edit',
      data:
       [ { companyid: '14',
           company: 'Dave',
           address1: '555 Main',
           address2: '',
           city: 'Sudbury',
           province: 'ON',
           postal: 'A1B2C3',
           country: 'Canada',
           officephone: '7058675309',
           faxphone: '',
           creationdate: '2019-07-02',
           notes: '',
           hide: '0' } ] }
    

    Here is the output just before process:

    request body { action: 'edit',
      data:
       [ { companyid: 14,
           company: 'Dave',
           address1: '555 Main',
           address2: '',
           city: 'Sudbury',
           province: 'ON',
           postal: 'A1B2C3',
           country: 'Canada',
           officephone: '7058675309',
           faxphone: '',
           creationdate: '2019-07-02',
           notes: '',
           hide: 0 } ] }
    

    Just a background on the changing of the data.... a while ago I had a problem in the link here, that is why I transform any strings to numeric that need be, there aren't any boolean, but I transform them now. I did try without any transformation, the problem is still the same.

    https://datatables.net/forums/discussion/55324/load-state-not-honouring-data

    Thanks!
    Dave

  • daduffydaduffy Posts: 31Questions: 5Answers: 1

    @allan

    I figured out the problem, and came up with a workaround in my server script. However, there still is an underlying problem that hasn't been fixed. Further, my workaround only addresses single row edits.

    In Editor's class there is the function _process which sets the id. The id is pulled from the req.body.data's key. However, when the bodyParser is set to bodyParser.urlencoded({ extended: true }) it strips the data's other keys and it is reduced to keys = '0'.

    In your editor.js file, the areas where the id is set is:

    case 11:
        keys = Object.keys(data.data);
        i = 0, ien = keys.length;
        _c.label = 12;
    case 12:
        if (!(i < ien)) return [3 /*break*/, 18];
        cancel = null;
        idSrc = keys[i];
        values = data.data[keys[i]];
        if (!(data.action === 'create')) return [3 /*break*/, 14];
        return [4 /*yield*/, this._trigger('preCreate', values)];
    case 13:
        cancel = _c.sent();
        return [3 /*break*/, 16];
    case 14:
        id = idSrc.replace(this.idPrefix(), '');
        return [4 /*yield*/, this._trigger('preEdit', id, values)];
    

    When I searched, I found that the keys was always '0', since the req.body.data had been transformed by bodyParser.

    I added this to my server script before the process call:

      var data = [], id = 0 ;
      id = req.body.data[ 0 ][ idSrc ] ;
      data[ id ] = {} ;
      Object.keys( req.body.data[ 0 ] ).forEach( function (key) {
        data[ id ][ key ] = req.body.data[ 0 ][ key ] ;
      } ) ;
      
      req.body.data = [] ;
      req.body.data[ id ] = data[ id ] ;
    

    Of note to anyone else reading this thread, this workaround WILL NOT work for multi row edits. My project will only ever have single line edits, so this is not an issue for me.

    @allan @colin I truly appreciate all of your help, you guys are the best!

    If you would like anything else to help sort out this problem for anyone else, by all means, let me know. Feel free to email me if you would like any sensative data as well; I am open to sending you access to my whole project.

    Thanks!
    Dave

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin

    Awesome to hear you've got a workaround. I've just sent you a PM to see if we can get to the bottom of the underlying issue.

    Allan

  • daduffydaduffy Posts: 31Questions: 5Answers: 1
    Answer ✓

    Not sure how to switch the answer, @colin or @allan , but I actually figured out this problem while working on a new project. I wanted to post the answer here, in case anybody was every dealing with this issue in the future.

    Turns out the problem was in the bodyParser, as we suspected.
    The following line of code was causing the problem.

    app.use( bodyParser.json( { limit: '100mb', extended: true } ) ) ;
    

    I am not an expert on the Express bodyParser, but the tool, it looks like, was stripping out the req.body.data's parameter, since there was only one, and bringing it down to just a flatter level... exactly what it is supposed to do.

    The bodyParser.json did this a little more that the urlencoded, and that cleared out the ID when it went into the server. By removing the json part of it, it actually leaves it in there.

    Not sure if more light needs to be shed on a 1.5 year old problem, but here is an actual solution, as opposed to just a workaround.

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

    Nice, thanks for remembering and reporting back!

    Colin

Sign In or Register to comment.