Is it possible to pass a JSON key as a string in the @Input() decorator in Angular?

I am currently working on implementing angular material autocomplete in a custom component that can be easily used throughout my code. The challenge I am facing is setting up dynamic arrays with different keys for each array.

Here is what I have attempted so far:

app.component.html

<app-autocomplete [items]="data.attributes" [field]="'caption.default'" inputType="text" inputPlaceholder="placeholder"></app-autocomplete>

autocomplete.component.ts

var str1="";
     var length= this.field.split(".");
     str1= "'"+length[0]+"']";
     console.log(length.length)
    for(var i=1;i<length.length;i++){

      if(i===length.length-1){
        str1= str1+"['"+length[i];
      }else{
        str1= str1+"['"+length[i]+"']";
      }

    }

    this.field=str1;
     console.log(this.field);

This will return ['abc']['xyz']

autocomplete.component.html

<mat-form-field class="example-full-width">
    <input type="{{inputType}}" placeholder="{{inputPlaceholder}}" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let option of items " [value]="option">
        {{option[field]}} 
      </mat-option> 
    </mat-autocomplete>
  </mat-form-field>

I also tried using "." like: "caption.default"

Unfortunately, it did not work as expected. Can anyone help me find a solution?

My goal is to create a generic component that can be easily utilized by filling in the necessary data through @Inputs. For example, if I have two JSON objects:

JSON-1

[{
    "caption": {
        "default": "Asset ID"
      }
},
{
    "caption": {
        "default": "Asset ID"
      }
}]

and My second JSON object is JSON-2

[{
    "name": {
        "anything": "Asset ID"
      }
},
{
    "name": {
        "anything": "Asset ID"
      }
}]

For the first JSON (json-1), I would use the following:

<app-autocomplete [items]="data.attributes" [field]="'caption.default'" inputType="text" inputPlaceholder="placeholder"></app-autocomplete>

And for the second JSON (json-2), I would use:

<app-autocomplete [items]="data.attributes" [field]="'name.anything'" inputType="text" inputPlaceholder="placeholder"></app-autocomplete>

My aim is to pass fields dynamically so that the component can traverse automatically and display the relevant data.

Answer №1

To achieve a similar outcome, I recommend using a pipe function or computing the data when triggering the input.

fields: Array<string> = [];

    // create an array with the specified path
    @Input() set field(fields: string) {
        this.fields = fields.split('.');
    }

    // retrieve the data using a pipe function
    getValue(option: any): string {
        let temp: any;
        if (this.fields.length > 0 && option) {
            this.fields.forEach(field => {
                temp = option[field];
            })
        }
        return temp;
    }

html

<mat-option *ngFor="let option of items " [value]="option">
    {{ getValue(option) }} 
</mat-option> 

Answer №2

While the solution may seem simple at first, there is a crucial mistake that needs to be addressed.

To clarify,

this.fields = field.split(".");
{{option[field]}} --->  {{option[fields[0]][fields[1]]}}

In simpler terms, you are attempting to access an attribute within an object that is part of an array. Thus, the correct way to retrieve this data would be:

items[index][ObjectAttr][innerObjAttr]

For example, in your sample JSON1 it should be:

`items[index][caption][default]`

However, what you are currently doing is:

items[index][[caption][default]]

This approach will not yield the desired results. It's important to adjust the syntax accordingly.

Answer №3

Big shoutout to @ukn and @shrivenkata pavan kumar mhs for helping me find the answer!

retrieveValue(Obj): any {
    var objPath=this.field.split(".");
      var s="Obj";
      for(var i=0;i<this.field.split(".").length;i++){
       s=s+"['"+objPath[i]+"']";
      }
     return eval(s);
    }

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

NodeJs app experiencing issues with Webpack code splitting functionality

Utilizing Webpack (version 4.43.0) to efficiently split a NodeJS application for AWS Lambda has presented a challenge for me. I've structured my code into two bundles: a compact `main` bundle consisting of my own code, and a bulky `vendors` bundle con ...

Creating a Popup with a Hazy Background: A Step-by-Step Guide

I've been working on implementing a popup on my existing page that opens 4.5 seconds after the page loads. I want to add a blur effect to the background when the popup appears. I've tried various methods to add the blur effect to the main div, bu ...

Exploring the World with AngularJS and Google Maps API through ngGeolocation

Having some difficulty displaying my geolocation on Google Maps API using a marker. I am utilizing the ng controller ngGeolocation and the http://angular-ui.github.io/angular-google-maps/ Previously, I hardcoded the marker and map location without any is ...

The React component was not able to receive any children as input

My Typescript-written React component is called GradientText.tsx: import React, { ReactNode } from "react" import { cn } from "@/lib/utils" const typeMap = { h1: "h1", h2: "h2", p: "p", } inte ...

Error: Unable to assign void to parameter type

Encountering TypeScript Error: Argument type (response: Response<DSBMannschaftDTO[]>) => void is not assignable to parameter type ((value:Response<DSBMannschaftDTO[]>) => (PromiseLike<void> | void)) null | undefined | undefined ...

Adjust ion-select label width across the entire screen in Ionic version 6

I recently began working on a fresh project using Ionic v6. As part of the development, I included a basic ion-select element in my HTML code: <ion-item> <ion-select placeholder="Select Option"> <ion-select-opti ...

Instructions on setting div opacity when Overflow is set to visibleExplanation on setting opacity for div with Overflow

In my HTML code, I have a div element and an image tag stacked one on top of the other. The div is smaller than the image. I have set the overflow property to visible for the div. My query is, when I add an image to the image tag, the content that overflow ...

What are some ways to enhance the content within a JWT?

After following this tutorial, I am interested in adding additional information to the token. Specifically, I would like to include an 'accessRights' field that can be used for user authorization in both the backend and Angular. Where should I i ...

Error encountered while running TypeScript compiler on Linux Mint: The require.paths has been eliminated

Just diving into the world of Node.js. My Linux Mint system is running node 0.9.5-pre and I utilized npm (1.1.70) to install TypeScript. However, upon attempting to run tsc, this error message pops up: Error: require.paths is removed. Use node_modules fol ...

What is the best way to spy on child components within an Angular application?

The Angular tutorials feature an example of a HeroesComponent with a child component named HeroesListComponent. Within the HeroesListComponent, there is a usage of the HeroesService to execute the getHeroes() function. In order to utilize the spyOn funct ...

Learning how to implement server side rendering in React JS through tutorials

After diving into the world of React js and mastering the basics, I successfully created web pages using this technology. I also honed my skills with node js and express. However, now I am faced with a new challenge: server side rendering. The tutorials av ...

Display a list of items in Angular using ng-repeat, and allow the full description to appear in full width

<div ng-controller = "MyController"> <ul class="items" > <div ng-repeat="item in colors" ng-class="{active:isActive(item)}" ng-click="select(item); whattoshow=!whattoshow"> <li class="col-md-3 col-sm-3 col-lg-3 co ...

Arranging json array according to alphabetical sections in angularjs 2

In the example below, I am working with JSON data that needs to be formatted and placed in a box according to specific criteria. The data sorted in A-B should go to a particular section, and it needs to be dynamic. Despite numerous attempts, I have not bee ...

Delete the content on a webpage using an Ajax jQuery request to transfer it elsewhere

Whenever I submit a form using an ajax post request, I receive values from the controller and manipulate the page based on those values. However, my issue is that I need to erase the values from the previous request when the form is submitted again. For in ...

Populate HTML form with return values using jQuery AJAX

I am struggling with retrieving values from jQuery/AJAX and displaying them in an HTML form within the index.php file. This is what my index.php looks like: <script type="text/javascript"> $(document).ready(function () { $('#display'). ...

What is the best way to incorporate the 'autoskip' functionality into chartjs?

Click here for an example I've been attempting to utilize the autoSkip functionality outlined in the documentation for chart.js: Visit this link for more information on autoSkip The current issue I'm facing is that my x-axis labels are o ...

Why are my animation states being shared among different instances of the component?

Why is the animation playing for both instances of the carousel component when interacting with just one call (e.g. clicking next or prev)? carousel.component.ts @Component({ selector: 'app-carousel', standalone: true, templateUrl: './c ...

At what point does the event loop in node.js stop running?

Could you please enlighten me on the circumstances in which the event loop of node.js terminates? How does node.js determine that no more events will be triggered? For instance, how does it handle situations involving an HTTP client or a file reading app ...

Transform the code provided by bundleMDX into an HTML string specifically for RSS, all the while utilizing the mdx-bundler

I am currently working on developing an RSS reader and I need to convert the code returned by bundleMDX into a string. This is necessary so that I can utilize it with ReactDOMServer.renderToStaticMarkup(mdx) in my project. You can find a similar implement ...

Transforming a function into an array in TypeScript

I attempted to use the map() function on a dataURL array obtained from the usePersonList() hook, but I am struggling to convert my function to an array in order to avoid errors when clicking a button. import Axios from "axios"; import React, { us ...