MVC Hierarchical grid - Load on demand - throwing Object reference error

Not Answered This post has 0 verified answers | 20 Replies | 2 Followers Thread's RSS feed.

Singh
Points 205
Replied On: Fri, Apr 28 2017 11:24 AM Reply

Hi,

I am trying to use a hierarchical grid using MVC 5. I am suppose to have three levels of data in the grid - parent , child and grand child.

I am able to bind the parent but not the child using Load on demand from the controller.

--Model
public class ParentViewModel
{
  public int PId {get; set;}
  public string Name {get; set;}
  public ICollection ChildDetails
}


Public class ChildViewModel
{
  public int CId {get; set;}
  public int PId {get; set;}
  public int CData {get; set;}
}

--View
@model Infragistics.Web.Mvc.GridModel

(Html.Infragistics().Grid(Model))

--Controller

private GridModel GetGridModel()
{  

            GridModel model = new GridModel();
            model.AutoGenerateColumns = false;
            model.AutoCommit = true;
            model.PrimaryKey = "PId";
            model.AutoGenerateLayouts = false;
            model.ID = "igGrid";

            model.LoadOnDemand = true;

            model.Columns.Add(new GridColumn { Key = "PId", Hidden = true, DataType = "number" });
            model.Columns.Add(new GridColumn { Key = "Name", HeaderText = "Parent Name ", DataType = "string" });
            model.DataSourceUrl = (Url.Action("BindParentDetails"));
           

            GridColumnLayoutModel childModel = new GridColumnLayoutModel();
            childModel.Key = "ChildDetails";
            childModel.PrimaryKey = "PID";
            childModel.ForeignKey = "CId";
            childModel.AutoGenerateColumns = false;
            childModel.Columns.Add(new GridColumn { Key = "CId", HeaderText = "Child ID", DataType = "number" });
            childModel.Columns.Add(new GridColumn { Key = "CData", HeaderText = "Child Data", DataType = "number" });
            childModel.DataSourceUrl = Url.Action("BindChildDetails");

            model.ColumnLayouts.Add(childModel);
            
            return model;
}


        public JsonResult BindParentDetails()
        {
            GridModel rModel = GetGridModel();

            var p = _service.GetPDetails();

            rModel.DataSource = p.AsQueryable();
            var res = rModel.GetData();
            return res;
        }

        public JsonResult BindChildDetails(string path, string layout)
        {
            var pid = path.Substring(path.LastIndexOf(':') + 1);


            GridModel grd = GetGridModel();

            var p = _service.GetChildDetails(pId);
            grd.DataSource = p.AsQueryable();
            var res = grd.GetData(path, layout);
            return res;
        }

When I run the solution it binds the parent grid correctly. On clicking the + icon it goes into BindChildDetails function and breaks on:

var res = grd.GetData(path, layout);

An exception of type 'System.NullReferenceException' occurred in Infragistics.Web.Mvc.dll but was not handled in user code

Additional information: Object reference not set to an instance of an object.

It has correct values in path and layout

grd.DataSource  is set correctly with the data from the DB.

The version of Infragistics.Web.Mvc we are using is 5.16.2.2040

Can anyone please help me with this?

  • Post Points: 20

All Replies

[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Mon, May 1 2017 9:08 AM Reply

Hello Singh,

Thank you for contacting Infragistics!

Looking at your code it appears you return the child and parent model/layout in GetGridModel, when you should have different methods for each level. Here is documentation and a sample on setting up Load on Demand in the igHierarchicalGrid:

https://www.igniteui.com/help/ighierarchicalgrid-load-on-demand

https://www.igniteui.com/hierarchical-grid/load-on-demand

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Tue, May 2 2017 3:15 AM Reply

Thanks Mike

I have tried as you suggested but still getting the same error

--Model
public class ParentViewModel
{
  public int PId {get; set;}
  public string Name {get; set;}
  public ICollection<ChildViewModel> ChildDetails
}


Public class ChildViewModel
{
  public int CId {get; set;}
  public int PId {get; set;}
  public int CData {get; set;}
}

-- View
@model Infragistics.Web.Mvc.GridModel

(Html.Infragistics().Grid(Model))


--Controller

private GridModel GetGridModel()

            GridModel model = new GridModel();
            model.AutoGenerateColumns = false;
            model.AutoCommit = true;
            model.PrimaryKey = "PId";
            model.AutoGenerateLayouts = false;
            model.ID = "igGrid";

            model.LoadOnDemand = true;

            model.Columns.Add(new GridColumn { Key = "PId", Hidden = true, DataType = "number" });
            model.Columns.Add(new GridColumn { Key = "Name", HeaderText = "Parent Name ", DataType = "string" });
            model.DataSourceUrl = (Url.Action("BindParentDetails"));
          

            GridColumnLayoutModel childModel = GetChildGridModel();

            model.ColumnLayouts.Add(childModel);
            
            return model;
}


private GridModel GetChildGridModel()
{
            GridColumnLayoutModel childModel = new GridColumnLayoutModel();
            childModel.Key = "ChildDetails";
            childModel.PrimaryKey = "CID";
            childModel.ForeignKey = "PId";
            childModel.AutoGenerateColumns = false;
            childModel.Columns.Add(new GridColumn { Key = "CId", HeaderText = "Child ID", DataType = "number" });
            childModel.Columns.Add(new GridColumn { Key = "CData", HeaderText = "Child Data", DataType = "number" });
            childModel.DataSourceUrl = Url.Action("BindChildDetails");
            return childModel ;

}
        public JsonResult BindParentDetails()
        {
            GridModel rModel = GetGridModel();

            var p = _service.GetPDetails();

            rModel.DataSource = p.AsQueryable();
            var res = rModel.GetData();
            return res;
        }

        public JsonResult BindChildDetails(string path, string layout)
        {
            var pid = path.Substring(path.LastIndexOf(':') + 1);


            GridModel grd = GetGridModel();

            var p = _service.GetChildDetails(pId);
            grd.DataSource = p.AsQueryable();
            var res = grd.GetData(path, layout);
            return res;
        }

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Tue, May 2 2017 10:18 AM Reply

Hello Singh,

Thank you for the update. Can you please attach a running sample, so I may debug it and see what specifically isn’t working in your scenario? When attaching you can attach with dummy data if needed. As well make sure to delete the packages folder so it can be attached to the forums. If you do not wish to attach it to the forums. You can set it to support@infragistics.com with the case number CAS-183529-C8M9T5 in the subject.

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Thu, May 4 2017 12:06 PM Reply

 Thank you.

I have emailed you.

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Fri, May 5 2017 9:37 AM Reply

Hello Singh,

Thank you for the update and your sample. I have looked into and have found why you are having this issue. In your BindChildDetails method there are two changes to make. First is when you are creating the child grid layout you are using the GridModel and the GetGridModel for the parent where as instead you should use the following:

GridColumnLayoutModel grd = GetChildGridModel();

Then when you call GetData on grd you are passing in the path and layout when you already filtering the data from the datasource by the parent id. So you will either want stop pre-filtering it or instead call:

var res = grd.GetData();

So when you are doing the filtering yourself it would look like the following:

public JsonResult BindChildDetails(string path, string layout)
        {
            var pid = path.Substring(path.LastIndexOf(':') + 1);
            int parentId = int.Parse(pid);

            GridColumnLayoutModel grd = GetChildGridModel();

            var p = PopulateChild(parentId);
            grd.DataSource = p.AsQueryable();
            var res = grd.GetData();
            return res;
        }

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Fri, May 5 2017 12:39 PM Reply

Hi Mike,

Thank you very much for your help.

It works perfectly now.

  • Post Points: 5
Singh
Points 205
Replied On: Fri, May 5 2017 1:00 PM Reply

Hi Mike,

I also want to add a dropdown and a textbox in the child row in the same grid.

I am able to find some links that show dropdowns in the hierarchical grid without load on demand but not with it.

Can you please suggest me some links where I can find a working example for the same i.e MVC Load on demand hierarchical grid with dropdowns and textbox in the child row.

Drop down values will be coming from the DB.

I would also need to set the default value of the drop down from the DB and save the value chosen in the DB so I want to access the controls in the controller.

It would be great if you can help me with this

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Mon, May 8 2017 10:28 AM Reply

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Wed, May 10 2017 10:58 AM Reply

Hi Mike,

The above links were very helpful.

I am able to show the drop downs and textboxes in the child grid but I am now stuck on Saving the data.

I have set the child grid's update URL but still it is not getting called:

Save button on the view :

<input type="submit" id="saveChanges" class="btn btn-block btn-grey" value="Save" />

(Tried with type="button" as well)

In controller

updating.ColumnSettings.Add(new ColumnUpdatingSetting

{

ColumnKey = "StatusValue",

EditorType = ColumnEditorType.Combo,

ComboEditorOptions = new ComboModel { TextKey = "Text", ValueKey = "Value", DataSource = ViewData["Status"], AutoComplete = true }

});

childModel.Features.Add((updating));

childModel.UpdateUrl = (Url.Action("UpdateChildren"));


public ActionResult UpdateChildren()

{

return View();

}


If I click on the save button it doesn't go into the UpdateChildren


Can you please help me with this?


Regards

S

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Wed, May 10 2017 3:47 PM Reply

Hello Singh,

Thank you for the update. Are you calling the saveChanges method in the saveChanges button’s click event?

Otherwise to save the changes in the grid you should call saveChanges:

https://www.igniteui.com/help/api/2016.2/ui.iggrid#methods:saveChanges

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Thu, May 11 2017 12:01 PM Reply

Thanks Mike

Yes I am calling it in the javascript but still it doesn't get triggered.

Please  note I am trying to call saveChanges in the child grid and not the parent grid.

I am using it like this:

$(document).ready(function () {

var grid = $("#igGrid")

grid.igGrid("saveChanges", function (data2) {

if (data2.Success === true) {

vex.dialog.alert({

className: 'vex-theme-os',

unsafeMessage: "Success"

});

}

}, function () {

vex.dialog.alert({

className: 'vex-theme-os',

unsafeMessage: "Failure "

});

});

 

});


UpdateChildren Action method is not getting called.

Can you please help me with this?

Regards

S

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Fri, May 12 2017 9:47 AM Reply

Hello Singh,

Thank you for the update. SaveChanges should be called on the main grid. And you will only have one update url that is setup on the parent band and it will have the transactions for both the parent grid and child grids. Please see the following sample that demonstrates editing in MVC:

https://www.igniteui.com/hierarchical-grid/editing-dataset

https://www.igniteui.com/help/api/2016.2/ui.ighierarchicalgrid#methods:saveChanges

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Singh
Points 205
Replied On: Tue, May 16 2017 6:29 AM Reply

Hi Mike,

I am able to save the changes now using the above links.

Thanks for that.

However I am having some issues -

1)  As you know I have 3 levels of band to be shown on the grid using load on demand. Sorting and paging seems to be working on parent and child grid but not on the grand child level (3rd band). Can you please suggest something?

2) On save if I am unable to save some of the rows in the grid (as per my business logic) I want to show those rows as highlighted and refresh the rest of the grid with new and saved data from the DB. Is this highlighting possible? Also when I refresh the grid I would want to maintain the state of the grid as it was open when the user saved it. For e.g if the grid was expanded by opening the parent , child and grand child level and the user clicked save so I want to refresh the grid but leave the grid as it was expanded earlier.

Regards

S

  • Post Points: 20
[Infragistics]Mike P
Points 23,560
Infragistics Employee
Replied On: Tue, May 16 2017 12:41 PM Reply

Hello Singh,

For paging, this depends upon if you want local or remote paging. If you want local you just have to set the type to local. If you want remote paging for child levels, you will have to handle this yourself. The reason the parent level works is you are passing the model down so the grid can then do what it needs with that. For the child levels you are just passing the data so you need to return the correct data based on the params of the request. You can access like the following:

this.Request.Params
this.Request.Params["page"]
this.Request.Params["pageSize"]

The “page” and “pageSize” are keys you can see what keys are in a request through the following:

this.Request.Params.AllKeys
or
this.Request.Params.Keys

What would be the reason you would be unable to save rows? You mean like they fail validation?

For persisting the page/state of the grid that will be up to you to save the state of the grid and set/reload it how you want after f]refresh or re-launch of the page after closing.

Sincerely,
Mike P.
Software Developer
Infragistics, Inc.
www.infragistics.com

  • Post Points: 20
Page 1 of 2 (21 items) 1 2 Next > | RSS