1

I am developing an app where there is a searchable database of references, and there is a management app that allows a user to edit the database. The public facing side uses Knockout JS communicating with the server via a RESTful API. The administration application uses express. Pages are rendered from templates using Handlebars. The edit view uses the same rendering code as the public view.

I am using connect-flash to send action result messages to editors. When a form is submitted to the page (used to add a new reference), then the flash messages are displayed as expected, however, for commands that are available on each item in the table view (like deleting a particular reference), I use an ajax call from a function defined in the view model. The call executes correctly and the action is performed, but the flash message is never displayed to the user. I have a custom middleware that collects the flash messages into a replacements object for the templates. When I log which messages are sent, I never see the message resulting from the delete call, so I am not just losing it on an extra refresh.

Here is the request handler that I am using:

var router = express.Router();
var client = solr.createClient(...);

router.get('/', function (req, res, next) {
    res.render('refs', req.replacements);
});

// This one is submitted via an html form post, and works
router.post('/new', function (req, res, next) {

    var doc = {};

    ... // Form reading and validation code

    client.add(doc, { commitWithin: 50 }, function (err, data) {

        if (err) {
            console.log(err);
            req.flash('error', 'A problem occurred during submit.'); //works
        } else { // Success            
            req.flash('yay', 'New reference successfully added.'); //works
        }

        res.redirect(303, '/refs?rows=1&q=id%3A' + newId);
    });
});

// This one is submitted via ajax in the view model. Action works, flash doesn't
router.delete("/:id(\\d+)", function (req, res, next) {

    var id = req.params.id;
    var query = 'q=id:' + id;


    var doc = undefined;
    client.get('refs', query, function (err, obj) {
        if (err) {
            req.flash('error', 'Unable to obtain a copy of object to delete for audit log. Reference not deleted.');
            res.redirect(303, '/refs');
        } else {
            doc = obj.response.docs[0];

            client.deleteByID(id, { commitWithin: 50 }, function (err, data) {
                if (err) {
                    console.log(err);
                    return req.flash('error', 'A problem occurred during delete submission.');
                } else { // Success
                    req.flash('yay', 'Reference successfully deleted.'); // Never seen
                }
            });
        }
    });

    res.redirect(303, url.format({
        pathname:"/refs",
        query:req.query,
    }));
});

I have tried changing the redirect to 278 to prevent the browser from handling the redirect transparently and then handling it in the success function of the ajax call, as per How to manage a redirect request after a jQuery Ajax call, but that didn't help.

Here is the client-side javascript which defines the view model:

function RefsViewModel(qString) {
    "use strict";
    var self = this;
    self.refs = ko.observableArray();

    $.ajax({
        // This makes the call which populates self.refs with observables
    });

    self.deleteRef = function (ref) {
        $.ajax({ // Makes an AJAX query to the server for the source
            url: "/refs/" + ref.id(),
            type: "DELETE",
            error: function (jqXHR) {
                console.log("ajax error " + jqXHR.status);
                alert("Error sending delete request");
            }
        });
    }
}

And the middleware I am using to collect the flash messages:

var flash = require('connect-flash');
function flashMessageCenter(req, res, next) {
    if(typeof req.replacements === "undefined") {
        req.replacements = {}
    }

    req.replacements.errorMessage = req.flash("error");
    req.replacements.yayMessage = req.flash("yay");
    req.replacements.infoMessage = req.flash("info");
    console.log(req.replacements);

    return next();
}
nmogk
  • 73
  • 5

0 Answers0