Can we use a switch statement instead of having multiple @Input()s in Angular?

When passing an attribute into my Angular component like this:

<my-component myAttribute></my-component>

I aim to modify a variable within the component that controls the CSS properties for width and height.

To simplify, I have predefined attribute values set up where using:

<my-component large>

Will automatically adjust the width and height variables to be 100 (resulting in 100px).

However, I am exploring the possibility of creating multiple criteria using @Input() without having numerous separate entries. Instead, could I potentially utilize a switch statement to achieve the same outcome?

I have made some attempts at implementing this approach, but all I see are red squiggly lines under the code.

My Inputs:

size = 50 // Default value

  @Input('small') set small(value) {
    this.size = !value ? 25 : this.size;
  }

  @Input('medium') set medium(value) {
    this.size = !value ? 50 : this.size;
  }

  @Input('large') set large(value) {
    this.size = !value ? 100 : this.size;
  }

  @Input('x-large') set xlarge(value) {
    this.size = !value ? 200 : this.size;
  }

Answer №1

There's a unique approach to solving this issue that may be considered unconventional. I am capable of executing it, but I cannot advise you on whether or not it should be used. Proceed with caution if you choose to explore this method.

This particular technique (accessible here for demonstration) eliminates the need for inputs and instead utilizes the root element of your component:

export class HelloComponent {
  size = '120';

  attributes = {
    'x-small': 50,
    'small': 75,
    'medium': 100,
    'large': 125,
    'x-large': 150,
  };

  constructor(
    private el: ElementRef<HTMLElement>
  ) { }

  ngOnInit() {
    this.setSize();
  }

  private setSize() {
    const attr = Object.keys(this.attributes).forEach(attr => {
      const hasAttribute = this.el.nativeElement.hasAttribute(attr);
      this.size = hasAttribute && this.attributes[attr] || this.size;
    });
  }

  getSize() {
    const myStyle = {
      width: this.size + 'px',
      height: this.size + 'px'
    };
    return myStyle;
  }

}

The functionality it provides involves searching for an attribute within the pre-defined attributes object and setting the corresponding value if found.

UPDATE When creating private functions, their scope is limited to the component itself, reducing potential external impacts and testing requirements.

For example, you can evaluate the size as follows:

it('should be 100px wide when setSize', () => {
  component['el'].nativeElement.setAttribute('medium', '');
  component.setSize();
  expect(component.size).toEqual(100);
});

This concept is known as an implementation detail, emphasizing the importance of testing the behavior rather than the internal workings of the function.

It is crucial to test all scenarios to prevent unintended consequences, such as handling cases where the attribute is not 'medium' but 'exxxtra-large'.

Adhering to this practice should streamline your testing process!

Answer №2

Instead of passing a number, consider passing the input as an object. This way, you can capture the value passed by using either:

a setter method (similar to your current approach) OR

https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter

ngOnChanges

https://angular.io/guide/component-interaction#intercept-input-property-changes-with-ngonchanges

If you choose to use a setter and assuming dimensions is an object being passed in, your code may look something like this:

private _width = 0;
private _height = 0;

@Input()
set dimensions(dimensions: any) {
  this._width = dimensions.width
  this._height = dimensions.height
  // You could add a switch case here
}

get width(): string { return this._width; }
get height(): string { return this._height; }

Answer №3

To efficiently manage the size of a child component within the parent component, you can control it and calculate it then send an object with various properties. The value can be retrieved through a single input named size.

Parent Component

<my-component size="this.childSize"></my-component>

Child Component

private _size: any;

@Input('size') set size(value) {
  this._size = value;

  const property = Object.keys(this.size)[0]; // expecting only 1 property

    switch (property):
      case 'small':
        // do something
        console.log(this.size[property]);
        break;
      case 'large':
        // do something
        break;
      default:
        // do something
}

public get size(): any {
  return this._size;
}

It is recommended to define your own type for childSize to specify and limit the possible properties. For example, objects may include:

{
  small: 15
}

{
  large: 35
}

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

Challenges with Initializing Angular 2 Router

I'm encountering a problem with the Angular 2 Router. My goal is to navigate through my application using a function that utilizes the navigate function from the Router, similar to how it's done in the official example. Here's what I curren ...

Running the JavaScript code on a webpage using Selenium WebDriver

I am currently in the process of creating an automated test for a website, and I am encountering some difficulty trying to execute a specific function within the site's code. Upon inspecting the developer tools, I have identified the function I need ...

Moving Rows Between AgGrids

Experimenting with the example provided in this link (Dragging Multiple Records Between Grids) within my React application: https://www.ag-grid.com/react-data-grid/row-dragging-to-grid/ I have some inquiries; How can I retrieve the selected rows for the ...

How can we improve our handling of cyclic requires and EventEmitter in our code?

My user service code looks like this: 'use strict'; let events = require('services/events'); module.exports = { create: function (data) { doCreate(data).then(user => { events.emit('user.create'); ...

JQuery email validation failing to function

I am new to JQuery and have created a basic validation script to verify email addresses. However, it does not seem to be working properly. Can anyone provide guidance on how to correct this issue? <script> $( "#email" ).blur(function() { var ...

Navigating pages with Jqueryor Using J

Currently, I am utilizing jQuery and AJAX to retrieve data from a remotely stored PHP file on a server. After successfully fetching the initial page and displaying the outcomes in an HTML table, I've encountered a new challenge. My goal now is to fetc ...

Issue with jQuery select box (roblaplaca) and its custom scroll bar functionality not functioning as expected

Recently, I implemented the custom select box script from . This script allows for two select boxes, where the second one updates dynamically using AJAX when there is a change in the first select box. Below is a sample of the HTML code: <option>One& ...

jQuery not functioning properly when attempting to add values from two input boxes within multiple input fields

I am facing an issue with a form on my website that contains input fields as shown below. I am trying to add two input boxes to calculate the values of the third input box, but it is only working correctly for the first set and not for the rest. How can ...

Customized link routing / Deep linking

I need some help. I am managing a standard website and I want to redirect custom URLs to specific pages when visitors access the site. For instance: - index.html should point to custom_index.cfm?custom_id=1&page_id=1&inc=index - about.html shou ...

Drop and drag to complete the missing pieces

Here is a drag and drop fill in the blanks code I created. The challenge I'm facing is that I want users to be able to correct their mistakes by moving words to the right place after receiving points. <!DOCTYPE HTML> <html> <head&g ...

Problem with flags series in Highcharts/Highstock

Can anyone help me figure out why not all the flags in the withdrawals series are displaying? For reference, you can view the following JS fiddle: https://jsfiddle.net/lucianpurcarea/5zxa0jsm/13/ The snippet of code below is responsible for creating the d ...

Identifying one of the two possible return types automatically

In my code, there is a function named isDone() that will return data from either an array of hashes or a dictionary of hashes: public async isDone() { this.startDelayedTasks(); await Promise.all(this._tasks); const hadErrors = this._failed.length &g ...

The scroll function is executed only one time

I'm currently working on implementing a sticky sidebar snippet using jQuery. However, I am facing an issue where the function within .scroll() is only executing once instead of on every scroll event. Can anyone help me identify what I might be doing i ...

The Node.js EventEmitter encounters an error stating `listener must be a function` when the `typeof` operator indicates that the value is a function, hint

Dealing with an object that is being interacted with by multiple node.js modules has presented some challenges. My goal is to allow certain modules to add eventListeners to the object. In my codebase, I have an events file where event emitters are attach ...

Having trouble retrieving spot price using Uniswap SDK due to a transaction error LOK

const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle( immutables.token0, immutables.token1, immutables.fee, amountIn, 0 ) I set up a pool on Uniswap V3 for two ERC20 dummy tokens by using the createPool() met ...

Having trouble getting Node.js to run Express.js and React.js simultaneously

My tech stack consists of reactjs for the frontend and expressjs for the backend API. I experimented with the following setup: { "name": "carweb", "version": "0.1.0", "private": true, "dependencies": { // list of dependencies }, "scripts ...

Utilize web workers for efficient processing of a limited number of files simultaneously in JavaScript

Utilizing the web worker concept for file uploads has resulted in creating a web worker for each selected file. The idea now is to optimize this process by creating 5 web worker threads to handle the first batch of five files, terminating them afterwards b ...

moment.js incorrectly interprets the month as the day instead of the actual day

I am currently using moment.js (moment-with-locales.js - v.2.14.1) in my project. My goal is to extract only the date from a datetime string and remove the time. However, when I use the .format() method of moment.js, I receive an incorrect date. The datet ...

Declaring and accessing class variables in Angular 4

I am facing an issue with the following TypeScript model: export class User { email: string; token: string; username: string; bio: string; image: string; constructor() {} } When I attempt to instantiate this model in another TypeScript file, ...

Is the functionality of this.value compatible with Firefox but not with Internet Explorer?

I am facing an issue with the onChange event on a select element. When I use alert(this.value), it works fine on Firefox, but not on Internet Explorer. What could be causing this discrepancy? Below is the code snippet in question: <select onchange="n ...