This is a migrated thread and some comments may be shown as answers.

ViewModel Object Property Undefined

4 Answers 522 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Mark
Top achievements
Rank 1
Mark asked on 12 Sep 2018, 06:55 PM

I have the following grid definition which displays data without issue:

@(Html.Kendo().Grid<HFITDashboard.UI.Models.Validation.ValidationViewModel>()
            .Name("dataValidationReportGrid")
            .Columns(column =>
            {
                column.Bound(v => v.ValidationId).Hidden(true);
                column.Bound(v => v.Name);
                column.Bound(v => v.EtlBatchJobId);
                column.Bound(v => v.EtlBatchJob.Frequency);
                column.Bound(v => v.ValidationSubTypeId).Hidden(true);
                column.Bound(v => v.ValidationSubType.Name).Hidden(true);
                column.Bound(v => v.ValidationSubType.ValidationType.Name).Hidden(true);
                column.Bound(v => v.Purpose).Hidden(true);
                column.Bound(v => v.CalendarDate).ClientTemplate(string.Format("{0}", "#= truncator(CalendarDate) #")).HtmlAttributes(new { title = "#= CalendarDate #" });
                column.Bound(v => v.ValidationQuery).ClientTemplate(string.Format("{0}", "#= truncator(ValidationQuery) #")).HtmlAttributes(new { title = "#= ValidationQuery #" });
                column.Bound(v => v.Threshold).Hidden(true);
                column.Bound(v => v.EmailMessage).Hidden(true);
                column.Bound(v => v.EmailRecipient).Hidden(true);
                column.Bound(v => v.WorksheetName).Hidden(true);
                column.Bound(v => v.PowerShellCommand).Hidden(true);
                column.Bound(v => v.Column1Description).Hidden(true);
                column.Bound(v => v.Column2Description).Hidden(true);
                column.Bound(v => v.Column3Description).Hidden(true);
                column.Bound(v => v.Column4Description).Hidden(true);
                column.Bound(v => v.Column5Description).Hidden(true);
                column.Bound(v => v.Column6Description).Hidden(true);
                column.Bound(v => v.Column7Description).Hidden(true);
                column.Bound(v => v.Column8Description).Hidden(true);
                column.Bound(v => v.Column9Description).Hidden(true);
                column.Bound(v => v.Column10Description).Hidden(true);
                column.Bound(v => v.Column11Description).Hidden(true);
                column.Bound(v => v.Column12Description).Hidden(true);
                column.Bound(v => v.Column13Description).Hidden(true);
                column.Bound(v => v.Column14Description).Hidden(true);
                column.Bound(v => v.Column15Description).Hidden(true);
                column.Bound(v => v.Column16Description).Hidden(true);
                column.Bound(v => v.Column17Description).Hidden(true);
                column.Bound(v => v.Column18Description).Hidden(true);
                column.Bound(v => v.Column19Description).Hidden(true);
                column.Bound(v => v.Column20Description).Hidden(true);
                column.Bound(v => v.AddDateTime).Hidden(true).Format("{0:MM/dd/yyyy}");
                column.Bound(v => v.LastMaintenanceDateTime).Format("{0:MM/dd/yyyy}");
                column.Bound(v => v.LastMaintenanceOperatorId).Hidden(true);
                column.Command(cmd =>
                {
                    cmd.Edit().Text(" ").HtmlAttributes(new { title = "Edit" });
                    cmd.Destroy().Text(" ").IconClass("k-icon k-i-trash").HtmlAttributes(new { title = "Delete" });
                    cmd.Custom("Validate").Text(" ").IconClass("k-icon k-i-check").Click("executeValidation").HtmlAttributes(new { title = "Execute Validation" });
                    cmd.Custom("Copy").Text(" ").IconClass("k-icon k-i-copy").Click("copyValidation").HtmlAttributes(new { title = "Copy Validation" });
                });
            })
            .ToolBar(tb => tb.Create().Text("Add New Validation"))
            .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("Validation"))
            .ColumnMenu()
            .Filterable()
            .Groupable()
            .Pageable()
            .Scrollable(s => s.Height(490))
            .Sortable()
            .Events(e =>
            {
                e.Edit("onEditGrid");
            })
            .DataSource(ds => ds
                .Ajax()
                .PageSize(7)
                .Model(model => model.Id(v => v.ValidationId))
                .Create(create => create.Action("Create", "Validation"))
                .Read(read => read.Action("Read", "Validation"))
                .Update(update => update.Action("Update", "Validation"))
                .Destroy(destroy => destroy.Action("Destroy", "Validation"))
                .Events(e => e.RequestEnd("onRequestEnd"))
            )
    )

 

The ViewModel is defined as:

public class ValidationViewModel
    {
        public ValidationViewModel()
        {
            EtlBatchJob = new EtlBatchJob();
            ValidationSubType = new ValidationSubType();
            ValidationSubType.ValidationType = new ValidationType();
        }
 
        [Display(Name = "Id")]
        public int ValidationId { get; set; }
 
        [Display(Name = "Name")]
        public string Name { get; set; }
 
        [Display(Name = "Etl Batch Job")]
        public int? EtlBatchJobId { get; set; }
 
 
        public EtlBatchJob EtlBatchJob { get; set; }
 
        [Display(Name = "Validation Sub Type")]
        public int? ValidationSubTypeId { get; set; }
 
        public ValidationSubType ValidationSubType { get; set; }
 
        [Display(Name = "Purpose")]
        public string Purpose { get; set; }
 
        [Display(Name = "Calendar Date")]
        public string CalendarDate { get; set; }
 
        [Display(Name = "ValidationQuery")]
        [Required]
        public string ValidationQuery { get; set; }
 
        [Display(Name = "Threshold")]
        public int? Threshold { get; set; }
 
        [Display(Name = "Email Message")]
        public string EmailMessage { get; set; }
 
        [Display(Name = "Email Recipient")]
        public string EmailRecipient { get; set; }
 
        [Display(Name = "Worksheet Name")]
        [Required]
        public string WorksheetName { get; set; }
 
        [Display(Name = "PowerShell Command")]
        [Required]
        public string PowerShellCommand { get; set; }
 
        [Display(Name = "Column 1 Description")]
        [Required]
        public string Column1Description { get; set; }
 
        [Display(Name = "Column 2 Description")]
        public string Column2Description { get; set; }
 
        [Display(Name = "Column 3 Description")]
        public string Column3Description { get; set; }
 
        [Display(Name = "Column 4 Description")]
        public string Column4Description { get; set; }
 
        [Display(Name = "Column 5 Description")]
        public string Column5Description { get; set; }
 
        [Display(Name = "Column 6 Description")]
        public string Column6Description { get; set; }
 
        [Display(Name = "Column 7 Description")]
        public string Column7Description { get; set; }
 
        [Display(Name = "Column 8 Description")]
        public string Column8Description { get; set; }
 
        [Display(Name = "Column 9 Description")]
        public string Column9Description { get; set; }
 
        [Display(Name = "Column 10 Description")]
        public string Column10Description { get; set; }
 
        [Display(Name = "Column 11 Description")]
        public string Column11Description { get; set; }
 
        [Display(Name = "Column 12 Description")]
        public string Column12Description { get; set; }
 
        [Display(Name = "Column 13 Description")]
        public string Column13Description { get; set; }
 
        [Display(Name = "Column 14 Description")]
        public string Column14Description { get; set; }
 
        [Display(Name = "Column 15 Description")]
        public string Column15Description { get; set; }
 
        [Display(Name = "Column 16 Description")]
        public string Column16Description { get; set; }
 
        [Display(Name = "Column 17 Description")]
        public string Column17Description { get; set; }
 
        [Display(Name = "Column 18 Description")]
        public string Column18Description { get; set; }
 
        [Display(Name = "Column 19 Description")]
        public string Column19Description { get; set; }
 
        [Display(Name = "Column 20 Description")]
        public string Column20Description { get; set; }
 
        [Display(Name = "Add Date Time")]
        public DateTime? AddDateTime { get; set; }
 
        [Display(Name = "Last Updated")]
        public DateTime? LastMaintenanceDateTime { get; set; }
 
        [Display(Name = "Last Updated By")]
        public string LastMaintenanceOperatorId { get; set; }
    }

 

Again, the grid displays data just fine. The issue is when I click the "Add New Validation" button, I get the following JavaScript error:

Uncaught TypeError: Cannot read property 'Frequency' of undefined
    at eval (eval at compile (kendo.all.js:194), <anonymous>:3:956)
    at init._rowsHtml (kendo.all.js:61016)
    at init._renderContent (kendo.all.js:61680)
    at init.refresh (kendo.all.js:61518)
    at init.proxy (jquery-3.3.1.js:10268)
    at init.trigger (kendo.all.js:124)
    at init._process (kendo.all.js:7333)
    at init._change (kendo.all.js:7290)
    at init.proxy (jquery-3.3.1.js:10268)
    at init.trigger (kendo.all.js:124)

 

The Frequency property is a property of the EtlBatchJob property of my ViewModel. My guess is that the EtlBatchJob property is not initialized, and therefore, undefined. When I edit the record, the Frequency property is displayed without issue.

I added a constructor to my ViewModel to initialize my object properties, but that doesn't seem to do anything - I still receive the error.

Should I just flatten-out my ViewModel to only contain simple value types or am I doing something wrong?

 

4 Answers, 1 is accepted

Sort by
0
Tsvetina
Telerik team
answered on 14 Sep 2018, 09:47 AM
Hi Mark,

When editing a nested property, you should declare a default value for it in the DataSource model, so new data items are initialized properly without undefined properties. See, for example, the Custom Editor demo. The Category field is a complex property, so there is a DefaultValue declared for it:
.DataSource(dataSource => dataSource
    .Ajax()
    .Batch(true)
    .ServerOperation(false)
    .Events(events => events.Error("error_handler"))
    .Model(model =>
    {
        model.Id(p => p.ProductID);
        model.Field(p => p.ProductID).Editable(false);
        model.Field(p => p.Category).DefaultValue(
            ViewData["defaultCategory"] as Kendo.Mvc.Examples.Models.CategoryViewModel);
    })
    .PageSize(20)
    .Read(read => read.Action("EditingCustom_Read", "Grid"))
    .Create(create => create.Action("EditingCustom_Create", "Grid"))
    .Update(update => update.Action("EditingCustom_Update", "Grid"))       
    .Destroy(destroy => destroy.Action("EditingCustom_Destroy", "Grid"))
)

private void PopulateCategories()
{
    var dataContext = new SampleEntities();
    var categories = dataContext.Categories
                .Select(c => new CategoryViewModel {
                    CategoryID = c.CategoryID,
                    CategoryName = c.CategoryName
                })
                .OrderBy(e => e.CategoryName);
 
    ViewData["categories"] = categories;
    ViewData["defaultCategory"] = categories.First();           
}

It is also possible to just initialize a new object with empty values.

Regards,
Tsvetina
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Mark
Top achievements
Rank 1
answered on 17 Sep 2018, 01:31 PM

Hi Tsvetina,

Thank you for the reply. I decided to keep it simple and just flattened my ViewModel and let AutoMapper handle the rest.

0
Anh
Top achievements
Rank 1
answered on 29 Mar 2019, 11:12 PM
I have similar problem and I tried your solution but it did not work. My grid is a nested grid. When I click the arrow to expand the child grid, I got the error and PopulateCategories() never got called.
0
Tsvetina
Telerik team
answered on 02 Apr 2019, 12:37 PM
Hello Anh,

Didn't it help to add a default value for the complex field in the DataSource? If you are still having the problem, please share the error message and the relevant code snippets, so we can try to track down the exact cause of the issue.

Regards,
Tsvetina
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Grid
Asked by
Mark
Top achievements
Rank 1
Answers by
Tsvetina
Telerik team
Mark
Top achievements
Rank 1
Anh
Top achievements
Rank 1
Share this question
or