Explore a recursive JSON format to identify matching numerical values in a Set using Typescript in Angular

My project involves an initial UI step where users need to check checkboxes with sequential IDs. The JSON structure for this task is outlined below:

{
  "categories": [{
    "name": "Product",
    "labels": [{
      "id": 1,
      "name": "I work on an asset (capital good).",
      "checked": false
    }, {
      "id": 2,
      "name": "I work on a consumer product.",
      "checked": false
    }, {
      "id": 3,
      "name": "I am not sure what type of product I work on.",
      "checked": false
    }
    ]
  }, {
    "name": "Goal",
    "labels": [{
      "id": 4,
      "name": "I want to improve the product's reliability.",
      "checked": false
    }, {
      "id": 5,
      "name": "I need information to identify root causes.",
      "checked": false
    }, {
      "id": 6,
      "name": "I need information about the product's environment.",
      "checked": false
    }, {
      "id": 7,
      "name": "I need information about customer requirements.",
      "checked": false
    }, {
      "id": 8,
      "name": "I need quantified information.",
      "checked": false
    }, {
      "id": 9,
      "name": "I am not sure what I need.",
      "checked": false
    }
    ]
  }
]
}

In Angular, I use the following code to render it:

component.html

<div class="row mt-lg-auto" *ngFor="let filter of filters['categories']">
    <div class="col-lg-12">
      <h4>
        {{filter['name']}}
      </h4>
      <div *ngFor="let label of filter['labels']">
          <div class="form-check">
            <input class="form-check-input"
                   type="checkbox"
                   value="{{label['id']}}"
                   id="{{label['id']}}"
                   [(ngModel)]="label['checked']"
                   (change)="changeCheck(label['id'], $event)"
            >
              <label class="form-check-label" for="{{label['id']}}">
                {{label['name']}}
              </label>
          </div>
      </div>
    </div>
  </div>

component.ts I import the JSON file from src/assets/ folder and save the id to a Set in order to avoid duplicate values when the user selects a checkbox.

import { Component, OnInit } from '@angular/core';
import * as FilterFunc from 'src/assets/FilterFunction.json';

const Filters: any = FilterFunc;

@Component({
  selector: 'explore-step1',
  templateUrl: './explore-step1.component.html',
  styleUrls: ['./explore-step1.component.css']
})
export class ExploreStep1Component implements OnInit {
  filters = Filters.default;
  selections = new Set();

  constructor() {
  }
  ngOnInit(): void {
  }
  changeCheck(id: number, event: any) {
    (event.target.checked) ?
      this.selections.add(id):
      this.selections.delete(id);
    console.log(this.selections);
  }
}

To handle a recursive JSON file with a specific structure, I utilize ngx-treeview. You can view the complete JSON structure here.

The most in-depth children nodes have the following key-value pair:

"value": {
     "label_ids": [relevant ids from the first json],
     "description": "some text to render"
}

If the children do not match this structure, then the "value" is null.

I aim to compare the selected checkbox values stored in the Set to the label_ids in the recursive JSON. If there is a match, I want to set the corresponding checked value to true.

Any suggestions on achieving this in Typescript/Angular?

Answer №1

My approach to solving this involved developing a Recursion Parsing Function specifically designed for handling JSON Structures.

  1. As part of the ngOnInit() method, I make a call to the service and pass the data to the parseTree function
  2. I apply recursive parsing logic to compare values with a specific Set
  3. Additional information, such as Font-Awesome class text, is included in the value structure to aid in rendering
  4. The updated JSON is then passed back to the relevant items variable

component.ts:

parseTree(factors: TreeviewItem[]) {
factors.forEach(factor => {
  // console.log(factor);
  if (!isNil(factor.value)) {
    let labels: number[] = factor.value['label_ids'];
    labels.forEach(label => {
      if(this.selected.findIndex(l => l == label) > -1) {
        factor.value['highlighted'] = true;
        factor.value['class'] = 'fas fa-flag';
      }
    });
  }
  if (!isNil(factor.children)) {
    this.parseTree(factor.children);
  }

});
this.items = factors;

}

In this context, selections represents a Set, with a predetermined value set within the ngOnInit() method:

ngOnInit() {
    this.selections.add(15);
    this.items = this.parseTree(this.service.getDataQualityFactors());
  }

Borrowing from the ngx-treeview example, I leverage the itemTemplate feature in my code and incorporate Font-Awesome icons alongside selections:

component.html

 <label class="form-check-label" *ngIf="item.value !== null && item.value['highlighted']">
        <i class="{{item.value['class']}}" aria-hidden="true" title="Highlighted" [ngClass]="{'marked': item.checked}"></i>
      </label>

Additionally, CSS classes are utilized to control the color changes of the Font Awesome icons:

.fa-flag {
  color: red;
}
.fa-flag.marked {
  color: green;
}

An illustrative StackBlitz Example Code is also available for reference.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble deserializing a deeply nested JSON array using Spring RestTemplate

I'm experiencing difficulty deserializing a nested JSON array from the response JSON using Spring Rest template. The JSON response I'm working with is structured as follows: [ { "creationTime": "2023-01-13", "c ...

Issue with Typescript and MaterialUI: Module 'csstype' not found or its type declarations

As I set up a new project with Vite, I encountered a perplexing issue when running tsc that resulted in 784 errors related to MUI being unable to locate the csstype module. Here is an example of the error: node_modules/@mui/styled-engine/index.d.ts:1:22 - ...

Encountering issue where the Angular application within the UWP project fails to load the second

I am facing a challenge with integrating my Angular project into a Universal Windows Platform (UWP) application. The Angular code functions flawlessly in the browser, but once incorporated into the UWP bundle, I encounter navigation issues. Technical Stac ...

The Alamofire encountered an issue with casting NSCFString type to a dictionary

I am attempting to utilize Alamofire for retrieving a response from a web-service. The service is providing a JSON-formatted string, but I am encountering the error: 'Could not cast value of type NSCFString to NSDictionary' Below is my code snip ...

Ways to retrieve a value from a span using the Document Object Model

sample.html <span id='char'>{{value}}</span> sample.ts console.log((<HTMLInputElement>document.getElementById('char'))) This code snippet will display <span id='char'>ThisIsTheValueupdated</sp ...

How to easily switch between multiple side navigation menus using Angular 4

Below is the structure of my components: app --app.component.html --app.component.ts -dashboard --dashboard.component.html --dashboard.component.ts -sales --sales.component.html --sales.component.ts -taxreports --taxreports.c ...

Function modifies global variable

What could be causing the global variable to change when using the function write_ACK_ONLY()? I'm passing the array rxUartBuffer to write_ACK_ONLY() as data = new Array(20), but upon checking the Log Output, it seems that the function is also modifyin ...

The error message "ng: command not found" popped up despite successfully installing the latest @angular/cli using npm linking

Here is the information about my current setup: Node version: v10.15.3 NPM version: 6.4.1 I attempted to run the following command: Command: npm i -g angular/cli An error occurred while executing: npm ERR! /usr/local/bin/git ls-remote -h -t ssh:// ...

Transferring JSON data to a non-RESTful WCF service

I am looking to implement a JavaScript function that can send an object as JSON to a WCF service for saving. Here is the current JavaScript code: <script> $(document).ready(function(){ $("#submitButton").click(function() ...

Currently focused on developing vertical sliders that can be manipulated by dragging them up or down independently

https://i.stack.imgur.com/NgOKs.jpg# I am currently working on vertical sliders that require dragging up and down individually. However, when I pull on the first slider, all sliders move together. The resetAllSliders button should also work independently, ...

Navigate the nested route of a child page starting from the main Root component

I am facing an issue with enabling nesting routes on the BarcodeScannerComponent component. I have attempted the following method, but it does not seem to work. The main challenge lies in accessing the nested route within the root component, which is app.c ...

What is the best way to ensure that my mat-slide-toggle only changes when a specific condition is met?

I'm having an issue with a function that toggles a mat-slide-toggle. I need to modify this function to only toggle when the result is false. Currently, it toggles every time, regardless of the result being true or false. I want it to not toggle when t ...

Access NgModel from NgForm

Is there a way to access the NgModel of a FormControl retrieved from the NgForm.controls object within its parent form, or directly from the form itself? Upon form submission, I pass the form as a parameter to a custom function: <form #myForm="ngForm" ...

Run a single feature file in Protractor by utilizing a specific tag

Is it possible to run just one feature file in Protractor? I am aware that I can specify the file in protractor.conf.js, but I have come across a different solution involving the use of a tag: To single out a specific feature file, you would include a tag ...

After the recent update to rc2, the Angular2 quickstart app has suddenly stopped functioning as expected

After updating my angular2 app, originally based on the tutorial / quickstart app, from rc1 to rc2, everything seemed fine: npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="325f5b5c5b5f5346515a72001c021c0302" ...

What should we name the type parameter?

After familiarizing myself with Typescript and understanding the concept of generic type T, I encountered an issue with a simple example. Can you pinpoint what's wrong? function test1<string>(x:number):boolean{ let s:string="hello"; if ...

Obtaining user profile pictures from Graph API for several users at the same time with the help of RxJs

I have created an ASP.NET Core API that can provide a list of users to an Angular service. The user data returned consists of certain properties like id, firstName, and lastName. My aim is for the Angular service to first fetch this user list from my API ...

Utilizing Typescript: Ensuring an array includes only specified values from an enum through strict enforcement

In my Angular application, I have an HTTP service that returns the allowed accesses for a specific user. The response structure is as shown below:- { "accessId": 4209318492034, "folderPath": "data/sample_folder/", ...

Exporting data to CSV using PrimeNG

Utilizing a PrimeNG grid, the data being retrieved from a service is paginated on the server side. This means that only the current page's data is received at a time. The relevant HTML code is displayed below: <p-dataTable *ngIf="displayTable" # ...

Nested *ngFor Loop in Angular 2

I am facing an issue with my classes Produkt and Werbedaten. The werbedaten class includes a produckt array. My goal is to display a werbedaten array containing the Produkts array using *ngFor export class Produkt { public artikelNummer: number; p ...