Can I create the dropdown tree using multiple APIS for different levels.

Hello everyone,


I'm looking for guidance on creating a dropdown tree with multiple APIs for different levels of hierarchy. Here's what I'm trying to achieve:


I have a dataset with over 100,000 data points organized into a hierarchy of five levels. Initially, I'd like to use an API to load the first two levels of the hierarchy. Then, upon selecting a node in the tree, I'd like to use additional APIs to load the hierarchy for that selected node.


I intend to implement this functionality within a Dropdown Tree component. Could someone please share their approach or any relevant resources to help me accomplish this task?


Thank you in advance for your assistance!


Best regards,

Gokala Sharma


8 Replies 1 reply marked as answer

PM Prasanth Madhaiyan Syncfusion Team March 6, 2024 02:18 PM UTC

Hi Gokala,


Greetings from Syncfusion support.


Based on the shared details, we understand that you want to initially add items to the Blazor Dropdown Tree component data source from the API service and also dynamically add items from the API call for the selected child items at your end. However, to achieve this, we have fetched data from an API using HttpClient in the Blazor application and assigned that data to the Dropdown Tree component data source. Similarly, we have added some additional items to the Child1 item based on the node selection with the help of the ValueChanging event.


Refer to the below code snippets.


[Index.razor]


@using Newtonsoft.Json

@using Syncfusion.Blazor.Navigations

@using Syncfusion.Blazor.Data

 

<SfDropDownTree TValue="int?" TItem="NodeResult" Placeholder="Select an employee" Width="500px" ValueChanging="ValueChanging">

    <DropDownTreeField TItem="NodeResult" DataSource="TreeData" ID="ProductID" Text="ProductName" ParentID="pid" HasChildren="haschild">

    </DropDownTreeField>

</SfDropDownTree>

 

@code

{

   

    public bool addChildItems { get; set; } = true;

    protected override async Task OnInitializedAsync()

    {

        // Load initial data

        await LoadData();

    }

    public List<NodeResult> TreeData = new List<NodeResult>();

    private async Task LoadData()

    {

        // Fetch data from the API and initialize TreeData

        using (HttpClient client = new HttpClient())

        {

            // Replace "YourApiUrl" with the actual URL of your API

            string apiUrl = https://localhost:7068/api/Nodes;

            // Send a GET request to the API

            var response = await client.GetAsync(apiUrl);

            // Check if the request was successful

            if (response.IsSuccessStatusCode)

            {

                // Read the response content as a string

                string data = await response.Content.ReadAsStringAsync();

                // Deserialize the JSON data into a List<NodeResult>

                TreeData = JsonConvert.DeserializeObject<List<NodeResult>>(data);

            }

        }

    }

    public async Task ValueChanging(DdtChangeEventArgs<int?> args)

    {

        // Check if the selected node has an Id of 2

        if (args.NodeData.Id == "2" && this.addChildItems)

        {

            // Fetch child items for "Child1" from the API

            using (HttpClient client = new HttpClient())

            {

                string apiUrl = $https://localhost:7068/api/Nodes/{args.NodeData.Id}/children;

                var response = await client.GetAsync(apiUrl);

                if (response.IsSuccessStatusCode)

                {

                    string data = await response.Content.ReadAsStringAsync();

                    List<NodeResult> childItems = JsonConvert.DeserializeObject<List<NodeResult>>(data);

                    // Find the parent node in the TreeData list

                    var parentNode = TreeData.FirstOrDefault(node => node.ProductID == 2);

                    // Check if the parent node is found

                    if (parentNode != null)

                    {

                        // Add each child item individually to the TreeData

                        foreach (var childItem in childItems)

                        {

                            TreeData.Add(childItem);

                        }

                        // Set HasChildren to true for the parent node

                        parentNode.haschild = true;

                    }

                }

            }

            this.addChildItems = false;

        }

    }

}

 


[NodesController.cs]


 

namespace BlazorApp1.Controllers

{

    [Route("api/[controller]")]

    [ApiController]

    public class NodesController : ControllerBase

    {

        [HttpGet]

        public IEnumerable<NodeResult> Get()

        {

            List<NodeResult> localData = new List<NodeResult>()

            {

                new NodeResult { ProductID = 1, ProductName = "Parent", pid = null, haschild = true },

                new NodeResult { ProductID = 2, ProductName = "Child1", pid = 1, haschild = false },

                new NodeResult { ProductID = 3, ProductName = "Child2", pid = 1, haschild = true },

                new NodeResult { ProductID = 4, ProductName = "Child3", pid = 1, haschild = false },

                new NodeResult { ProductID = 5, ProductName = "SubChild1", pid = 3, haschild = false },

                new NodeResult { ProductID = 6, ProductName = "SubChild2", pid = 3, haschild = false },

            };

            var data = localData.ToList();

            var queryString = Request.Query;

            if (queryString.Keys.Contains("$filter"))

            {

               

            }

            else

            {

                return data;

            }

        }

 

        public class NodeResult

        {

            public int? ProductID { get; set; }

            public string ProductName { get; set; }

            public int? pid { get; set; }

            public bool? haschild { get; set; }

        }

 

        [HttpGet("{parentId}/children")]

        public IEnumerable<NodeResult> GetChildren(int parentId)

        {

            // Fetch child items based on the parent ID

            // You can replace the logic below with your actual data retrieval logic

            List<NodeResult> childItems = new List<NodeResult>()

            {

                new NodeResult { ProductID = 8, ProductName = "Child1-SubChild1", pid = parentId, haschild = false },

                new NodeResult { ProductID = 9, ProductName = "Child1-SubChild2", pid = parentId, haschild = true },

                new NodeResult { ProductID = 10, ProductName = "Child1-SubChild2-SubChild1", pid = 9, haschild = false },

                new NodeResult { ProductID = 11, ProductName = "Child1-SubChild2-SubChild2", pid = 9, haschild = false },

                new NodeResult { ProductID = 12, ProductName = "Child1-SubChild2-SubChild3", pid = 9, haschild = true },

                new NodeResult { ProductID = 13, ProductName = "Child1-SubChild2-SubChild3-SubChild1", pid = 12, haschild = false },

                new NodeResult { ProductID = 14, ProductName = "Child1-SubChild2-SubChild3-SubChild2", pid = 12, haschild = false },

            };

            return childItems;

        }

    }

}


For your reference, we have attached the sample.


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/BlazorApp1-839899061.zip


Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.



GS GOKALA SHARMA March 13, 2024 03:32 AM UTC

In my case, I am using the dropdown in the data grid component. I have tried this approch but the said event " ValueChanging " is not getting triggered. 
My case has Tvalue as the string.



PM Prasanth Madhaiyan Syncfusion Team March 13, 2024 10:50 AM UTC

Hi Gokala,


Based on the shared details, we have prepared a sample by setting the TValue as a string type for the Dropdown Tree component and rendered the SfDropDownTree component inside the Grid column edit template. While checking on our end, the ValueChanging event triggered without any issues.


For your reference, we have attached the sample and gif file.


Sample and GIF: Attached as a zip file.


Check out the attached sample, and if the issue still persists, could you please replicate the issue in the attached sample or share the replicated sample along with the video footage of the issue? Based on that, we will investigate and provide you with a prompt solution. Kindly get back to us with the requested details.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorDropdownTreeInsideGrid_c5123936.zip


GS GOKALA SHARMA March 15, 2024 11:34 AM UTC

Thank you, but now data is not getting populated in the existing dropdown tree.




PM Prasanth Madhaiyan Syncfusion Team March 15, 2024 12:11 PM UTC

Hi Gokala,


Based on the shared details, we have checked the mentioned scenario in the Dropdown Tree component by rendering it inside the Grid component, but we were unable to replicate the mentioned scenario at our end.


For your reference, we have attached the sample.


Sample: Attached as a zip file.


Please check out the attached sample. If the issue still persists, could you please replicate the issue in the attached sample or share the replicated sample of the issue? Based on that, we will investigate and provide you with a prompt solution. Kindly get back to us with the requested details.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorDropdownTreeInsideGrid_8a849f8c.zip


GS GOKALA SHARMA March 15, 2024 01:19 PM UTC

If you check the video dropdowntree is only constructed till subchild1, although we have data below this hierarchy, that data is not getting populated in the dropdowntree.

This gives the impression that the event is not getting triggered.



Attachment: 20240315183947_f52edff9.zip


GS GOKALA SHARMA March 18, 2024 12:46 PM UTC

Yes, the event is getting triggered, but the API response is not added in the dropdown tree to construct the level below the selected level.



PM Prasanth Madhaiyan Syncfusion Team March 20, 2024 01:43 PM UTC

Hi Gokala,


Based on the shared video footage, you have clicked the SubChild1 node in the Dropdown Tree component at your end. However, in our first update, we mentioned, 'we have added some additional items to the Child1 item based on the node selection with the help of the ValueChanging event.' If you want to add items from the API call for the SubChild1 child item when you select this node at your end, you just need to make the following changes.


[Index.razor]


 

<SfGrid DataSource="@GridData" AllowPaging="true" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" Height="315">

    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Normal"></GridEditSettings>

    <GridColumns>

        <GridColumn Field=@nameof(NodeResult.ProductID) HeaderText="Order ID" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn>

        <GridColumn Field=@nameof(NodeResult.ProductName) HeaderText="Product Name" EditType="EditType.DropDownEdit" Width="150">

         <EditTemplate>

             @{

 

                    <SfDropDownTree ID="ProductName" TValue="string?" TItem="NodeResult" Placeholder="Select an employee" Width="500px" ValueChanging="ValueChanging">

                        <DropDownTreeField TItem="NodeResult" DataSource="TreeData" ID="ProductID" Text="ProductName" ParentID="pid" HasChildren="haschild">

                        </DropDownTreeField>

                    </SfDropDownTree>

             }

               

         </EditTemplate>

        </GridColumn>

    </GridColumns>

</SfGrid>

@code

{

    public class NodeResult

    {

        public string? ProductID { get; set; }

        public string? ProductName { get; set; }

        public int? pid { get; set; }

        public bool? haschild { get; set; }

    }

    public bool addChildItems { get; set; } = true;

    protected override async Task OnInitializedAsync()

    {

        // Load initial data

        await LoadData();

    }

    public List<NodeResult> GridData = new List<NodeResult>();

    public List<NodeResult> TreeData = new List<NodeResult>();

    private async Task LoadData()

    {

       // Fetch data from the API and initialize TreeData

        using (HttpClient client = new HttpClient())

        {

            // Replace "YourApiUrl" with the actual URL of your API

            string apiUrl = https://localhost:7068/api/Nodes;

 

            // Send a GET request to the API

            var response = await client.GetAsync(apiUrl);

 

            // Check if the request was successful

            if (response.IsSuccessStatusCode)

            {

                // Read the response content as a string

                string data = await response.Content.ReadAsStringAsync();

 

                // Deserialize the JSON data into a List<NodeResult>

                TreeData = JsonConvert.DeserializeObject<List<NodeResult>>(data);

            }

        }

    }

    public async Task ValueChanging(DdtChangeEventArgs<string?> args)

    {

     

        // Check if the selected node has an Id of 5

        if (args.NodeData.Id == "5" && this.addChildItems)

        {

            // Fetch child items for " SubChild1" from the API

            using (HttpClient client = new HttpClient())

            {

                string apiUrl = $https://localhost:7068/api/Nodes/{args.NodeData.Id}/children;

                var response = await client.GetAsync(apiUrl);

 

                if (response.IsSuccessStatusCode)

                {

                    string data = await response.Content.ReadAsStringAsync();

                    List<NodeResult> childItems = JsonConvert.DeserializeObject<List<NodeResult>>(data);

 

                    // Find the parent node in the TreeData list

                    var parentNode = TreeData.FirstOrDefault(node => node.ProductID == "5");

 

                    // Check if the parent node is found

                    if (parentNode != null)

                    {

 

                        // Add each child item individually to the TreeData

                        foreach (var childItem in childItems)

                        {

                            TreeData.Add(childItem);

                        }

 

                        // Set HasChildren to true for the parent node

                        parentNode.haschild = true;

                    }

                }

 

            }

            this.addChildItems = false;

        }

 

    }

 

   

}


For your reference, we have attached the sample.


Sample: Attached as a zip file.


Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorDropdownTreeInsideGrid_4b7aa3e8.zip

Marked as answer
Loader.
Up arrow icon