Best practice for spreading computed values in Angular 2

I am struggling to make computed values work with @Input properties.

Unfortunately, the initial value propagation is not functioning correctly.

https://plnkr.co/edit/1MMpOYOKIouwnNc3uIuy

I have two components: App (the root component with a template-driven form) and NumComponent (a child component that simply stores the typed value).

When passing the attribute [useThree]="true" to NumComponent, I want to set the default value to '3' in NumComponent.

However, I am unable to find a way to achieve this without using setTimeout.

Is there a method to propagate the initial value without relying on setTimeout?


Edited on 5/5

App component

@Component({
  selector: 'my-app',
  template: `
    <div>
      <form novalidate #form="ngForm">
        <app-num name="num" ngModel [useThree]="true"></app-num>
      </form>
      <pre>{{form.value | json}}</pre>
    </div>
  `
})
export class App {}

NumComponent

export const NumValueAccessor = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => NumComponent),
  multi: true
};

@Component({
  selector: 'app-num',
  template: `<input [(ngModel)]="num" type="text" (ngModelChange)="updateValue()" />`,
  providers: [NumValueAccessor]
})
export class NumComponent implements ControlValueAccessor {
  num = 0;

  // I want to set the literal number 3 to the `num` property
  // when `useThree` is true.
  @Input() useThree = false;

  onChange = (_: any) => {};

  updateValue(num = this.num) {
    this.onChange(String(num));
  }

  writeValue(value: string): void {
    if (this.useThree) {
      /**********
       * ISSUE
       **********/
      // This code does not work as expected. Even though the `NumComponent`
      // has a value of 3 after running this code, the internal FormComponent
      // value of AppComponent remains an empty string.
      // this.num = 3;
      // this.updateValue(3);

      // Using setTimeout resolves this issue. However, I am looking for an
      // alternative to achieve this without relying on setTimeout.
      // setTimeout(() => {
      //   this.num = 3;
      //   this.updateValue(3);
      // }, 0);

      // Is there any other way to propagate the computed initial value?
      this.num = 3;
      this.updateValue(3);

      /**********
       * ISSUE
       **********/

      this.useThree = false;
      return;
    }
    this.num = Number(value);
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {}

  setDisabledState(isDisabled: boolean): void {}
}

It appears that the parent component fails to recognize the propagated value during initialization.

Answer №1

It seems like there might be some room for interpretation in understanding the issue at hand. However, a potential solution that aligns with your needs could involve the following:

let _includeThree = false;
@Input() set includeThree(value: boolean) {
     _includeThree = value;
     if (_includeThree) {
         this.num = 3;
     }
}

By implementing this approach, any adjustments to the includeThree input property from the parent component will trigger the code within the designated setter method mentioned above.

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

Show images from an array of base64 image data

I am currently facing an issue while trying to display images in base64 format within a RadListView component. Within the loop of the component, I have the following code snippet: let base64ImageSource = new ImageSource; base64ImageSource = fromBase64(re ...

Is it advisable to send a response in Express.js or not?

When working with Express.js 4.x, I'm unsure whether to return the response (or next function) or not. So, which is preferred: Option A: app.get('/url', (req, res) => { res.send(200, { message: 'ok' }); }); Or Option B: ...

Exploring ways to loop through objects in a React application

I'm trying to figure out how to modify the code below to iterate through a custom object I have created. function itemContent(number) { return ( <div > <div className="item"> <div className="itemPic& ...

Using Javascript to trigger a setTimeout function after the user's mouse leaves

There is a div that pops up when the user's mouse exits the webpage, containing a survey pertaining to my website. I want to avoid prompting users to take the survey if they move their cursor out of the page within the first few minutes of browsing. ...

The slash character is escaped by the RegExp constructor, but the dot character is

Consider the following code: console.log(new RegExp('.git')); console.log(new RegExp('scripts/npm')); which produces the following output: /.git/ /scripts\/npm/ The puzzling question here is - why does it escape the slash in &a ...

PHP script failing to execute if/else statement during AJAX request

I am currently developing a website that heavily relies on Ajax, and I have chosen to use codeigniter for its construction. On the site, there is a form with the post method, and this form is submitted using an Ajax request that calls a function containi ...

Angular 2: It is essential to have a distinct instance for Signature Pad

I am seeking assistance with utilizing the signature pad feature in order to capture multiple signatures. Below is a snippet of my code. I have 'n' number of employees and would like each employee to input their signature into the designated box ...

In order to locate a matching element within an array in a JSON file and update it, you can use Node

Good day, I have a script that updates the value in a JSON file const fsp = require('fs').promises; async function modifyNumberInFile() { try { let data = await fsp.readFile('example.json'); let obj = JSON.parse(dat ...

Passing objects to Angular 4 routes while maintaining Query Params unchanged

I'm currently working with Angular 4 and I need to pass an object to the router without updating query parameters. user.component.ts this.router.navigate(["/profile",{ action: 'edit', user: {id: 1, name: 'test', email: &apo ...

What is the process for removing a mesh that has been uploaded using a function and then added to an Object3D?

// Defining variables for 3 obj models: cushion, backrest, and frame, and a group variable chair01 to include all 3 obj models var cushion; var backrest; var frame; var chair01 = new THREE.Object3D(); ...

The column is not properly aligned

I am facing a challenge in aligning 3 elements using bootstrap while working with Angular 8. To include only the necessary CSS from Bootstrap (such as col-md and col classes), I have added the following to my styles array: "styles": [ "src/ ...

JQuery is having issues with $(this) and the find function not working properly

I am attempting to access a child of the div with the class form-group, specifically, I want to display the value of the input element. <div class="form-group"> <label>text</label> <input name="text" type="text" class="form-co ...

Issue: The hydration process has failed due to a discrepancy between the initial UI and the server-rendered content when utilizing the Link element

Exploring Next.js, I stumbled upon the <Link/> component for page navigation. However, as I utilize the react-bootstrap library for my navbar, it offers a similar functionality with Nav.Link. Should I stick to using just Link or switch to Nav.Link? ...

Encountering a "400 Bad Request" error when using Ajax within WordPress

I've been trying to submit a form using Ajax within a plugin. I had two plugins, the first one was initially working but has stopped now and I can't seem to find any errors. I don't think the issue lies in the code itself, but I'm feeli ...

Guide on detecting errors when parameters are not provided with req.params in Node.js

My question revolves around a piece of code that I have been working on. Here is the snippet: const express = require('express') const app = express() app.get('/test/:name', (req, res) => { const {name} = req.params; res.send(`P ...

Detecting changes in arrays in Vue.js 2

Below is a simplified version of the code : <template> /* ---------------------------------------------- * Displaying a list of templates, @click to select the template /* ---------------------------------------------- <ul> ...

Converting JSON object settings to a string causes an error as it is not a valid function

For my project, I have been provided with a JSON object that contains various settings, some being strings and others booleans. One thing I am struggling with is adding an animation name from the object that is stored in a variable. aniFx.move(inner, { ...

Animating the Three.js Globe camera when a button is clicked

Struggling to create smooth camera movement between two points, trying to implement the function below. Currently working with the Globe from Chrome Experiments. function changeCountry(lat, lng) { var phi = (90 - lat) * Math.PI / 180; var theta = ...

What is the list of NPM packages already included in the AWS Lambda execution environment?

I was surprised to discover that the aws-sdk NPM module comes preinstalled in AWS Lambda using nodejs8.10. I couldn't find any information online about this. Are there other node.js modules that are also pre-installed in AWS Lambda? ...

Modify the AJAX data in Datatables without directly modifying the elements

I am currently working with a Datatable that is being populated through AJAX, and everything is going smoothly. However, I am looking for a way to include some shortcuts to send requests to the server. The issue lies in how I can modify the data being sent ...