Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout.Validation not showing error messages for property that is loaded after initial rendering

I have a Knockout.Validation scenario which I think would be fairly common but haven't found a solution from searching around the web and various answers on this site.

The property that I am validating does not get added to the knockout observable until after an ajax call. When validation gets triggered the validation fails and is an error in my validation group but the error message does not get shown on the page. I have made sure all the validation is hooked up by adding validation to a property that does exist when initial render happens and the message shows for that.

I know I could set a default for the property but I wouldn't expect you would have to do that. When i manually add the validation message with the validationMessage databind property it throws a js error because the property doesn't exist when knockout does its first pass through.....Uncaught TypeError: Unable to process binding "validationMessage: function (){return BlogPost().Title }" Message: Cannot read property 'extend' of undefined.

See this plunk for an example...http://plnkr.co/edit/OhUw8wP2uNypulbcOIbz?p=preview .

    self.Errors = ko.validation.group(this, { deep: true });
    self.Count(self.Errors().length);
    if (self.Errors().length === 0) {
        alert("no errors");
    }
    else {
        self.Errors.showAllMessages();
    }

It is using require js but that is not causing any issues as for a standard scenario the validation message shows.

What am I missing here to get this working?

like image 543
JohnG Avatar asked Oct 20 '22 14:10

JohnG


2 Answers

This is pretty clean... move your observables up to the main viewmodel, and leave the updateBlogPost to be just a method (no properties... as it should be).

This allows you to call self.Errors.showAllMessages() after you've loaded the blog post. Not sure you need the update method after this change?

function EditBlogPostViewModel(params) {

    var self = this;
    self.BlogPost = ko.observable({});
    self.ErrorsCount = ko.observable(0);

    self.Test = ko.observable("").extend({ required: true });
    self.Count = ko.observable(0);
    self.Errors = ko.validation.group(this, { deep: true });
    self.Count(self.Errors().length);

    blogApiService.getCategories().then(function (categories) {
         return blogApiService.getBlogPost(params.id).then(function (post) {
             self.BlogPost(new BlogPost(post, categories));
             self.Errors.showAllMessages();
        });
    });

}

EditBlogPostViewModel.prototype.updateBlogPost = function () {
    var self = this;
    if (self.Errors().length === 0) {
        alert("no errors");
    }
    else {
        self.Errors.showAllMessages();
    }
};
like image 83
Brett Green Avatar answered Oct 22 '22 22:10

Brett Green


set deep: true in self.errors property,

self.errors = ko.validation.group(self, { deep: true });

and set this to display error messages,

ViewModel.errors.showAllMessages(true);         

Hope it works!

like image 28
KimboSlice Avatar answered Oct 22 '22 22:10

KimboSlice