Fields return undefined when clicking add new record in grid

1 Answer 38 Views
Grid Toolbar
john
Top achievements
Rank 1
john asked on 21 Nov 2024, 02:02 PM | edited on 21 Nov 2024, 02:26 PM

When clicking the Add new record button on a grid from the Toolbar.Create method I am getting an error: kendo.all.js:3314  Uncaught TypeError: Cannot read properties of undefined (reading 'IsActive'). I'm using a ViewModel that is as follows:


public class PersonAddressViewModel
{
    public List<PersonInfo>? PersonInfoList { get; set; }

    public List<PersonAddress>? PersonAddressList { get; set; }

    public PersonInfo? Person { get; set; }

    public PersonAddress? Address { get; set; }
}

 

which is referencing these:

public partial class PersonInfo
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(120)]
    [Unicode(false)]
    public string Name { get; set; }

    public int Age { get; set; }

    [Required]
    [StringLength(10)]
    [Unicode(false)]
    public string Sex { get; set; }

    [Required]
    [StringLength(120)]
    [Unicode(false)]
    public string CreatedBy { get; set; }

    public DateTime CreatedDate { get; set; }

    [StringLength(120)]
    [Unicode(false)]
    public string? UpdatedBy { get; set; }

    public DateTime? UpdatedDate { get; set; }

    public bool IsActive { get; set; }

    [InverseProperty("FkPersonInfoNavigation")]
    public virtual ICollection<PersonAddress>? PersonAddresses { get; set; } = new List<PersonAddress>();
}

public partial class PersonAddress
{
    [Key]
    public int Id { get; set; }

    [StringLength(120)]
    [Unicode(false)]
    public string StreetAddress { get; set; }

    [StringLength(120)]
    [Unicode(false)]
    public string City { get; set; }

    [StringLength(2)]
    [Unicode(false)]
    public string State { get; set; }

    [StringLength(10)]
    [Unicode(false)]
    public string Zip { get; set; }

    [Column("FK_PersonInfo")]
    public int FkPersonInfo { get; set; }

    [ForeignKey("FkPersonInfo")]
    [InverseProperty("PersonAddresses")]
    public virtual PersonInfo FkPersonInfoNavigation { get; set; }
}

 

This is my cshtml:

@(
    Html.Kendo().DataSource<PersonAddressViewModel>()
        .Name("DsPerAddVM")
        .Ajax(datasource => datasource
            .ServerOperation(false)
            .Model(model =>
            {
                model.Id(perAdd => perAdd.Person.Id);
                model.Field(perAdd => perAdd.Person.Id).Editable(false);
                model.Field(perAdd => perAdd.Person.IsActive).DefaultValue(true);
                model.Field(perAdd => perAdd.Person.Name).DefaultValue("Enter Name");
                model.Field(perAdd => perAdd.Person.Age).DefaultValue(0);
                model.Field(perAdd => perAdd.Person.Sex).DefaultValue("Optional");
                model.Field(perAdd => perAdd.Person.CreatedBy).Editable(false).DefaultValue("Some User");
                model.Field(perAdd => perAdd.Person.CreatedDate).Editable(false).DefaultValue(DateTime.Now);
                model.Field(perAdd => perAdd.Person.UpdatedBy).Editable(false);
                model.Field(perAdd => perAdd.Person.UpdatedDate).Editable(false);
                model.Field(perAdd => perAdd.Address.Id).Editable(false);
                model.Field(p => p.Address.FkPersonInfo).Editable(false);
            })
            .Read(read => read.Action("KendoRead", "Home"))
            .Create(create => create.Action("KendoCreate", "Home"))
            .Update(update => update.Action("KendoUpdate", "Home"))
            .Destroy(destroy => destroy.Action("KendoDelete", "Home"))
        )
)

<div>
    @(
        Html.Kendo().Grid<PersonAddressViewModel>()
        .Name("UserGrid")
        .Columns(columns =>
        {
            columns.Bound(perAdd => perAdd.Person.IsActive);
            columns.Bound(perAdd => perAdd.Person.Name);
            columns.Bound(perAdd => perAdd.Person.Age);
            columns.Bound(perAdd => perAdd.Person.Sex);
            columns.Bound(perAdd => perAdd.Address.StreetAddress);
            columns.Bound(perAdd => perAdd.Address.City);
            columns.Bound(perAdd => perAdd.Address.State);
            columns.Bound(perAdd => perAdd.Address.Zip);
            columns.Command(command => command.Destroy());
        })
        .ToolBar(toolbar =>
        {
            toolbar.Create();
            toolbar.Save();
            toolbar.Search();
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .Scrollable()
        .DataSource("DsPerAddVM")
    )
</div>

 

My grid loads the data as expected with the following methods (image attached):

public ActionResult KendoRead([DataSourceRequest] DataSourceRequest dsRequest)
{
    List<PersonAddressViewModel> perAddList = KendoViewServices.GetGridData(_context);

    return Json(perAddList.ToDataSourceResult(dsRequest));
}

public static List<PersonAddressViewModel> GetGridData(TestJohnCrudOpContext context)
{
    context = context;

    List<PersonAddressViewModel> perAddList = [];
    PersonAddressViewModel GetPerAddVm = new()
    {
        PersonInfoList = [],
        PersonAddressList = []
    };
    GetPerAddVm.PersonInfoList = context.PersonInfo.ToList();
    GetPerAddVm.PersonAddressList = context.PersonAddresses.ToList();

    foreach (PersonInfo person in GetPerAddVm.PersonInfoList)
    {
        PersonAddressViewModel perAddVm = new()
        {
            Person = new PersonInfo
            {
                Id = person.Id,
                Name = person.Name,
                Age = person.Age,
                Sex = person.Sex,
                CreatedBy = person.CreatedBy,
                CreatedDate = person.CreatedDate,
                UpdatedBy = person.UpdatedBy,
                UpdatedDate = person.UpdatedDate,
                IsActive = person.IsActive
            }
        };

        foreach (PersonAddress address in GetPerAddVm.PersonAddressList.Where(w => w.FkPersonInfo == person.Id))
        {
            perAddVm.Address = new PersonAddress
            {
                Id = address.Id,
                StreetAddress = address.StreetAddress,
                City = address.City,
                State = address.State,
                Zip = address.Zip,
                FkPersonInfo = address.FkPersonInfo
            };
        }
        perAddList.Add(perAddVm);
    }

    perAddList.ToList();

    return perAddList;

 

I've used this ViewModel to load and edit a standard HTML table with no issues. Also, updating the grid or performing a deletion works without error. I can tell that it is cutting off the first property of each field prior to the "." but I can't find a solution to correct this. 

1 Answer, 1 is accepted

Sort by
0
Accepted
Mihaela
Telerik team
answered on 26 Nov 2024, 09:58 AM

Hello John,

Thank you for sharing the relevant code snippets.

Since the Grid columns bind to properties of a complex object (i..e, "Person.IsActive", "Person.Name". and etc.), specify the complex objects "Person" and "Address" in the Model() configuration of the DataSource, as per the example below:

@(
    Html.Kendo().DataSource<PersonAddressViewModel>()
        .Name("DsPerAddVM")
        .Ajax(datasource => datasource
            .ServerOperation(false)
            .Model(model =>
            {
                model.Id(perAdd => perAdd.Person.Id);
                model.Field(perAdd => perAdd.Person.Id).Editable(false);
                model.Field(perAdd => perAdd.Person).DefaultValue(new PersonInfo()
                {
                    IsActive = true,
                    Name = "Enter Name",
                    Age = 0,
                    Sex = "Optional",
                    CreatedBy = "Some User",
                    CreatedDate = DateTime.Now
                });
                model.Field(perAdd => perAdd.Person.UpdatedBy).Editable(false);
                model.Field(perAdd => perAdd.Person.UpdatedDate).Editable(false);
                model.Field(perAdd => perAdd.Address.Id).Editable(false);
                model.Field(p => p.Address.FkPersonInfo).Editable(false);
                model.Field(perAdd => perAdd.Address).DefaultValue(new PersonAddress()
                {
                    StreetAddress = "Enter StreetAddress...",
                    City = "Enter City...",
                    State = "Enter State...",
                    Zip = "Enter Zipcode..."
                });
            })
            .Read(read => read.Action("KendoRead", "Home"))
            .Create(create => create.Action("KendoCreate", "Home"))
            .Update(update => update.Action("KendoUpdate", "Home"))
            .Destroy(destroy => destroy.Action("KendoDelete", "Home"))
        )
)

Would you give this example a try and let me know if the issue is resolved at your end?

 

Regards,
Mihaela
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

john
Top achievements
Rank 1
commented on 26 Nov 2024, 01:07 PM

Thank you so very much! Worked like a charm. I'm new to Kendo, so I didn't even realize I could do that.
Mihaela
Telerik team
commented on 26 Nov 2024, 04:23 PM

Thank you for the update, John. I am glad that the provided solution helped you resolve the issue.

If you have any additional questions, don't hesitate to share them :)

Best,
Mihaela

Tags
Grid Toolbar
Asked by
john
Top achievements
Rank 1
Answers by
Mihaela
Telerik team
Share this question
or