Model Validation

Hey,
I have been trying to catch errors from my viewmodel while using PostBackHandlers:

    dotvvm.postbackHandlers["sidepanelHandler"] = function SidepanelHandler(options) {
       ...

        function startLoading(button) {
            ...
        }

        function stopLoading(button) {
            ...
        }

        return {
            execute: function (callback, args) {
                let button = args.sender;
                startLoading(button);

                const result = callback().then(
                    function (result) {
                        stopLoading(args.sender);
                        // if success close panel
                        return result;
                    },
                    function (result) {
                        stopLoading(args.sender);
                        return result;
                    }
                );

                return result;
            }
        }
    }

Everything works fine until I check from errors serverside: For exemple:

this.AddModelError(v => v.Item, "Error message!");
Context.FailOnInvalidModelState();

How can I check for those errors before closing the panel? (if those AddModelErrors happen, don’t stopLoading but don’t close the panel. If everything is fine, stopLoading and close panel)

When the postback fails on server-side validation

  1. The second function in .then( will be called instead of the first function
  2. In the phase where you call the stopLoading function, the errors should be in dotvvm.validation.errors array (and all errors will be cleared if it succeeded)

I’ve been trying the second .then() and even catch() but it always run the first then().

How can access errors from “dotvvm.validation.errors” ? I’ve been trying loops and it doesn’t work.
I tried to look in “Access validation errors from JS” documentation page but it’s
empty.

Ah, sorry, it works slightly differently. The postback handlers run in two phases

  1. the request to the server is made, this happens in the callback function. I’ll rename it to next, it is similar to the “call next” logic of AspNetCore middlewares. This throws if we didn’t get any readable reponse (network failure, HTTP 500, …)
  2. commit: the postback changes are applied to the viewmodel. This throws if the changes couldn’t be applied to the viewmodel, for example because of validation errors.

This is how you could implement your logic:

return {
    execute: async function (next, args) {
        let button = args.sender;
        startLoading(button);
        
        let commit
        try {
            commit = await next()
        }
        catch (error) {
            // hard error: network failure, HTTP 500
            throw error
        }

        return async () => {
            try {
                const result = await commit()
                // success
                stopLoading(args.sender);
                return result
            } catch (error) {
                // logical failure: validation failure, concurrency mode interrupted the postback
                throw error
            }
        }
    }
}
1 Like

Oh I tried this approach to await for results but it looks like I forgot a few things… The code above is working, thank you!