Creating a dynamic user interface in Angular 6 that successfully tracks changes without reliance on the parent

As I delve into the world of Angular, I am faced with a challenge in creating a reusable component that will be bundled into an npm module. The issue lies in the UI change detection aspect.

In order for the component to function properly, the application first needs to make an API call to fetch the necessary data for setup, followed by some initialization steps within the component.

this.dataService.getData().subscribe((data) => {
   this.data = data;
   this.npmComponent.init(this.data);
});


<app-npm-component></app-npm-component>

Within my component, there are additional setup tasks that need to be executed initially and then it must continuously monitor changes in the data, rerun certain setup tasks, and update the UI accordingly.

@Component({
...,
changeDetection: ChangeDetectionStrategy.OnPush
});

...

init(setupData: any): void {
    this.cdr.detectChanges();
    this.data = setupData;
}

<ul *ngIf="data.arrayOfStuff">
    <li *ngFor="let item of data.arrayOfStuff">{{item}}</li>
</ul>

The standard ChangeDetection implementation is throwing an error: NullInjectorError: No provider for ChangeDetectorRef! This occurs because the data is not being passed from the parent via the template.

What is the correct approach to handle such scenarios? Your insights are greatly appreciated.

Edit: I have discovered the solution using ViewChild.

@ViewChild(NpmComponent, {static: false}) npmComponent: NpmComponent;

Answer №1

Insert an input within the child element

<app-npm-component [data]="setupData"></app-npm-component>

and define in the child component's class

@Input() data;

Angular will automatically detect changes to inputs.

You can also accomplish this by subscribing with the async pipe.

In the parent component

setupData$ = this.dataService.getData();

and pass the data to the child component using the async pipe

<app-npm-component [data]="setupData$ | async"></app-npm-component>

No need for manual subscriptions.

If you want to manipulate the data with a function, use map

setupData$ = this.dataService.getData().pipe(map(data => yourFunction(data)));

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

Is there a way to extract values from a particular object?

Currently, I am utilizing a JSON server to establish a straightforward login system. The data stored on the server is structured as follows: { "users": [ { "name": "user1", "password": "pass1", "email": "<a href="/cdn-cgi/l/emai ...

Setting dynamic values for SASS mixins in Angular 2 with Ionic 2

In my SCSS file, I have created a mixin to generate a progress bar. @mixin progressBarMix($name, $size, $perc, $color, $colorBack) { .progressBarWrapper { &#{$name} { $sizeFill: $size / 100 * $perc; .progressBarEndFilled { b ...

What is the best way to locate and access a JSON file that is relative to the module I am currently working

I am in the process of creating a package named PackageA, which includes a function called parseJson. This function is designed to accept a file path pointing to a JSON file that needs to be parsed. Now, in another package - PackageB, I would like to invok ...

What is the best way to dynamically update form fields in a database after making a selection in a <select> component?

Currently, I have a form that displays a list of stars (stellar objects) with a <select> control and two <inputs>. I am seeking guidance on how to populate the two inputs from the database when the user changes the selection in the <select&g ...

What are the steps to styling a component with CSS Emotion?

I am facing an issue with using a theme with TypeScript in this component const buttonDisabled = css` color: ${({ theme }) => theme.color}; `; Is there a way to correctly type this component? Error: No overload matches this call. Overload 1 of 2, & ...

Lost Vuex struggles when it is manually navigating a route in Vue-router

Exclusively on Safari browser, I encounter an issue when manually entering the URL in the navigation bar after logging in. For example, if I type "http://x.x.x.x:8080/gestione", the browser loses the vuex store state (specifically the gest_user module with ...

Unusual behavior in sorting values with JavaScript

I have spent hours trying to figure this out, and the only conclusion I can come to is that when there are 14 elements to sort, it doesn't function properly, but with thirteen elements, it works perfectly. My goal is to sort DIV elements based on the ...

Having trouble with JSFIDDLE not functioning properly on my website

I'm having an issue with implementing a JSFIDDLE on my web form. The fiddle itself is working perfectly fine, but for some reason, I can't get it to work on my page. Can someone please help me figure out what mistake I might be making? Here is th ...

Exploring ways to locate a specific text within a URL using nodeJS

Here is a simple code snippet with a problem to solve: var S = require('string'); function checkBlacklist(inputString) { var blacklist = ["facebook", "wikipedia", "search.ch", "local.ch"]; var found = false; for (var i = 0; i < b ...

Ways to execute the pdf.js node demonstrations?

I've been attempting to run the pdf.js node examples, specifically getinfo.js. Unfortunately, I encountered an issue that resulted in the following error: C:\Repositories\pdf.js>node getinfo.js node:internal/modules/cjs/loader:1080 thro ...

Developing dynamic-sized tuples in TypeScript

Recently, I was attempting to develop a zipper for arrays. For instance, if the user inputs 3 arrays with sizes of 3, 5, and 12, the output array of tuples would be the size of the largest array. The output consists of tuples containing elements at a speci ...

Receiving an error when triggering an onclick event for a checkbox in TypeScript

I am creating checkboxes within a table using TypeScript with the following code: generateTable(): void { var table = document.getElementById("table1") as HTMLTableElement; if (table.childElementCount == 2) { for (var x = 0; x < 2; x++) ...

Ways to verify whether an array contains any of the specified objects and then store all those objects in Supabase

Perhaps the title of my question is not very clear, but I find it difficult to summarize in just one line. To provide context, it would be best to see the JavaScript query I'm making for Supabase and its response. The data: [ { title: 'Th ...

Uploading images using multipart in react is causing an error and cannot be completed

Trying to upload images in the database using multipart is causing an error from the API saying 'Files can't be uploaded". Checking the API in postman shows it is working fine there. There seems to be an issue with my code, but I can't ...

Issue with font-size changes using css variables in Angular not updating in browser for specific fields

Utilizing CSS variables, I have implemented a feature that allows users to adjust the font size to small, medium, or large. While this functionality works correctly for most fields, there are certain instances where the value is applied but not displayed. ...

The position of a jQuery element gets reset when both the show and stop animations are used

When I use jQuery's .position() to place an element, everything works fine. But as soon as I display an animation and then cancel it with an ajax call, the position of the element resets. function displayMessage(msg) { var $messageEl = $('#u ...

Creating a unique Nest.js custom decorator to extract parameters directly from the request object

I am working with a custom decorator called Param, where I have a console.log that runs once. How can I modify it to return a fresh value of id on each request similar to what is done in nestjs? @Get('/:id') async findUser ( @Param() id: stri ...

JQuery datepicker is functioning properly only after an alert when loaded with AJAX

Here's a puzzling question I have encountered. I implemented a field with a datepicker functionality. This field gets loaded into a div through an AJAX call. To sum it up, everything seems to be in working order.. But there's a strange issue. I ...

What could be causing the failure of this web component using shadow DOM when the HTML code includes multiple instances of the component?

Recently, a question was raised on this platform regarding the use of Selenium to access the shadow DOM. Curious about this topic, I delved into the MDN article Using shadow DOM and decided to replicate the code on my local machine. Surprisingly, it worked ...

What is the best way to access the local Express server that is located in the same directory as the frontend project

This is the structure of my project - backend > node_modules > .env package-lock.json package.json server.js frontend > index.html style.css script.js server.js import dotenv from 'dotenv'; dotenv.config(); import express from &apo ...