OnPush strategy and template updates: Propagating modifications to the parent component

I am currently facing an issue with a parent component that consists of two templates. The first template simply displays data-bound text, while the second template contains a child component responsible for updating the data model. Both the parent and child components use ChangeDetectionStrategy.OnPush.

The problem arises when the data updates initiated from the child component's ngOnInit function are not being detected by the change detection mechanism in the parent component. This results in the parent component displaying the value set in the constructor of the child component, instead of the value set in the ngOnInit function.

I have explored various approaches, such as using markForCheck and @Output events in the child component, but these solutions did not work as expected due to the parent-child relationship being established through ng-template rather than direct component nesting.

I am seeking suggestions on the cleanest and most Angular OnPush-friendly approach to pass data from a ng-template created child component to its parent, while maintaining loose coupling between components and services.

Answer №1

You have a solid understanding of using observables, async pipes, and the OnPush strategy. However, delving a bit deeper into the Angular component lifecycle events is essential to mastering these concepts.

Let's break it down in a simplified version:

  1. Parent component constructor()
  2. Child component constructor()
  3. Parent component onInit() - evaluates @Input templates and ngIf directives
  4. Child component onInit() - triggers changes to properties used in the parent
  5. Parent afterViewInit()

It's crucial to note that when the onInit in the child component is called, the directives in the parent component have already been evaluated. Essentially, the content inside the [ngIf] template is already set, eliminating the need for additional change detection or updates.

It's important to avoid altering data used in the parent component from the child component's onInit(), as this can lead to unexpected issues.

Waiting for all components to be fully instantiated before triggering changes ensures that all views are updated properly.

For instance, in your child component:

setTimeout(()=> this.dataService.setValue("hello"), 1000) 

This approach also works if you use markForCheck in the ngAfterViewInit of your parent component:

ngAfterViewInit(): void {
    this.changeDetector.markForCheck();
}

Alternatively, if you avoid using *ngIf, the value will be re-evaluated.

<div><b>Value from regular div: </b>{{ dataService.value | async }}</div>

While these workarounds may be effective, it's best practice to refrain from altering data in the child component's onInit to ensure a smoother functioning.

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

Traverse the JSON array in a loop

I am currently facing an issue with looping through a JSON array that I am passing to PHP. At this point, I am only passing one array and receiving the same array back from the PHP file. While I can loop through the data in JavaScript, I am encountering er ...

Omit the <span> tag when exporting to XLS format

Currently, I have a functioning jQuery DataTable that utilizes the TableTools plug-in and includes <span> elements in one of the columns for each row. When clicking on the export button, my goal is to exclude or hide the <span> elements from t ...

The power of negative multiplication in TypeScript and React

I am working with a state variable called sortDirection const [sortDirection, setSortDirection] = useState<1 | -1>(1); My goal is to allow a button to toggle the state variable like this setSortDirection(sortDirection * -1); However, I encounter a ...

Steps to have index.html display when running the build command in a Svelte project:

Greetings everyone, I'm brand new to using Svelte and have a question that's been on my mind. I recently developed a small app in Svelte that works perfectly fine during development. However, when I run npm run build for production, the output ...

Having trouble updating values in Vue3 when accessing the next item in an object?

I'm attempting to allow my users to browse through a collection of various items. Take a look at the records object below: 0: {id: 1, pipeline_id: 1, raw: '1', completion: null, processed: 0, …} 1: {id: 2, pipeline_id: 1, raw: '2&apo ...

Turning XSD into TypeScript code

Stumbling upon this tool called CXSD, I was intrigued. The documentation describes cxsd as a streaming XSD parser and XML parser generator designed for Node.js and TypeScript (optional but highly recommended). It seemed like the perfect solution for my ne ...

avoid loading javascript in ajax layer

After struggling for days to find answers online and unsuccessfully trying different codes, I discovered a way to use ajax to dynamically change the contents of a div element and display different sliders. Here are the files if you want to take a look: Fi ...

When utilizing Vue components, the issue of "setattr" arises when trying to assign

Having recently started using Vue.js, I encountered an issue while trying to implement components. Interestingly, the code worked perfectly fine before implementing components. I'm facing an error that is proving to be quite challenging to understand ...

The term 'App' is being referenced as a value when it is intended to be a type. Perhaps you meant 'typeof App'?

I am eager to master Typescript with React through hands-on experience, so I recently made the manual transition from JavaScript to TypeScript in my create-react-app. However, when working with my default testing file App.test.ts: import { render, screen ...

Parcel js is encountering difficulties running the same project on Ubuntu

I have encountered an issue with my JavaScript project when trying to run it on Ubuntu using parcel 2 bundler. The code works perfectly fine on Windows, but in Ubuntu, I am facing errors. Despite trying various solutions like cleaning the cache and reinsta ...

Achieving optimal hardware performance for WebGL compatibility is essential

Lately, I have been exploring the world of Three.js to create impressive 3D scenes in WebGL. To ensure compatibility for all users, I have also developed versions using Three's CanvasRenderer which may not be as detailed but can still function on brow ...

Retrieving and storing data using jQuery's AJAX caching feature

When utilizing jQuery's $.ajax() method to perform an XHR based HTTP GET request to obtain a partial of HTML from a Ruby on Rails website, I encounter an issue. Specifically, every time a user clicks on tabbed navigation, I refresh an HTML table with ...

Utilizing TypeScript in Kendo UI for JQuery

I have implemented KendoUI for JQuery using TypeScript. Here is an excerpt from my "package.json" file: "dependencies": { "@progress/kendo-theme-material": "^3.19.2", "@progress/kendo-ui": "^2020.3.915 ...

Tips for utilizing AJAX to send two values to PHP for comparison

How can I use AJAX to compare two values (#cpassword and #password) to see if they match? I've been attempting it, but it seems like I only get the value of '#cpassword'. Here is my cpassword-check.js file: // Validate confirm password whi ...

What is the purpose of the "Dot" symbol in the "runtimeArgs" property of the launch.json file in Visual Studio Code?

As I opened my Visual Studio Code today, a notification greeted me about a new update. Without hesitation, I went ahead and installed it, assuming it would be like any other update I've had in the past. However, after updating to version 1.22.1, I enc ...

Save Component Characteristics in a type-safe array

Is it possible in Svelte to define a strongly typed array that matches the properties exported by a specific component? For instance, if I have the following code snippet, const things = [], is there a way for Svelte to recognize that each item within the ...

Is there a way for me to access the names of the controls in my form directly from the .html file?

I have a list where I am storing the names of my form controls. In order to validate these form controls, I need to combine their names with my code in the HTML file. How can I achieve this? Below is my code: .ts file this.form = this.formBuilder.group({ ...

Is it possible to retrieve the value from the searchbar on the server?

I'm seeking assistance on how to retrieve the user-entered value from a search form on my HTML page in my server.js file. I understand that the name/value pair will be cityCode=something, but I'm unsure of the next steps. HTML: <form c ...

Autocomplete feature in MUI allows filtering to begin after typing at least 3 characters

I've encountered an issue with the Autocomplete MUI component I'm using to filter a list of checkboxes. The popup with options should remain open at all times, but I only want the filtering to be triggered when the user input is more than 3 chara ...

Tips for configuring a function to only be called once, even when the page is reloaded

I'm currently facing an issue with making a Post request upon component Mount. Every time the user reloads the page or there's a change in state, the function gets called again due to the useEffect hook, resulting in multiple requests being sent. ...