Sending data from a Parent component to a Child Component in Angular using the Pass API with an array return

Within this context, I am endeavoring to transmit the values of the bookingInfo array (assigned as

this.bookingInfo = bookings.responseObj.txnValues;
) to my child component. The current setting pertains to my parent component.

 @Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit{
  lineChart = ['line_chart1', 'line_chart2', 'line_chart3', 'line_chart4', 'line_chart5'];
  value = ['33.5M', '67.9M', '90.9M', '09.9M'];
  names = ['cancellations', 'Bookings', 'Modifications', 'Revenue' ];
  bookingInfo = [];

  ngOnInit() {

     this.getBookingInfo();
    }

  getBookingInfo() {
          const params = [];
          params.push({code: 'dateType', name: 'BOOKING'});
          params.push({code: 'fromDate', name: '2019-01-01'});
          params.push({code: 'toDate', name: '2019-12-31'});

          this.ServiceHandler.getTxnInfo([], params).subscribe(
            bookings => {
              this.bookingInfo = bookings.responseObj.txnValues;
              console.log(this.bookingInfo);
          });
      }

}

The file for my dashboard component is named dashboard.component.html.

<app-summary-chips [lineChart]="lineChart[0]" [value] = "value[0]" [name] = "names[0]" [data] = "bookingInfo"></app-summary-chips>

This serves as the child component.

@Component({
  selector: 'app-summary-chips',
  templateUrl: './summary-chips.component.html',
  styleUrls: ['./summary-chips.component.scss']
})
export class SummaryChipsComponent implements OnInit {
  @Input('lineChart') lineChart: string;
  @Input('value') value: string;
  @Input('name') name: string;
  @Input() data: [];

  ngOnInit() {

   console.log('line chart: ', this.lineChart);
    console.log(this.data);
  }

}

This corresponds with the content in summary-chips.component.html

<div class="l-content-wrapper c-summary-chip oh" >
  <div class="c-summary-chip__value">{{value}}</div>
  <div class="c-summary-chip__txt">{{name}}</div>

  <div id= "{{lineChart}}" class="c-summary-chip__graph ">
  </div>
</div>

However, upon executing console.log(this.data); within the child component, it displays an empty array.

Answer №1

The process of setting the data or assigning a value to data is not happening where it should be. To successfully set data to a variable, you must first initialize or set the data that is being passed from the parent component.

UPDATE

You are attempting to pass asynchronous data to a child component. There are various solutions to achieve this. For instance, you can utilize ngOnChanges instead of ngOnInit:

ngOnChanges() {
    console.log(this.data);
}

Alternatively, you can use *ngIf to postpone the initialization of the posts components:

<app-summary-chips *ngIf="bookingInfo" [lineChart]="lineChart[0]" [value] = "value[0]" [name] = "names[0]" [data] = "bookingInfo"></app-summary-chips>

Answer №2

Due to the time it takes for your service handler to fetch data, the this.bookingInfo variable will be updated after a delay, resulting in no initial value being displayed in the child component.

To resolve this issue, consider implementing the change detection strategy. For more information on how to do this, please refer to the resources provided below:

https://example.com/angular/change-detection

https://example.com/api/core/ChangeDetection

Once you have implemented this solution, any updates to this.bookingsInfo will trigger the ngOnChanges() method in the child component, providing both the previous and new values of this.bookingsInfo rather than just the initialization with onInit().

Answer №3

If you're encountering an empty list in your child component, it may be due to the list updating within a subscription, which doesn't trigger the child component in Angular to detect property changes.

A quick solution is to pass the observable itself to the child component and then subscribe to the value changes within the child.

Code snippet from your dashboard component:

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit{
  lineChart = ['line_chart1', 'line_chart2', 'line_chart3', 'line_chart4', 'line_chart5'];
  value = ['33.5M', '67.9M', '90.9M', '09.9M'];
  names = ['cancellations', 'Bookings', 'Modifications', 'Revenue' ];
  bookingInfoObservable;

  ngOnInit() {
     this.getBookingInfo();
    }

  getBookingInfo() {
          const params = [];
          params.push({code: 'dateType', name: 'BOOKING'});
          params.push({code: 'fromDate', name: '2019-01-01'});
          params.push({code: 'toDate', name: '2019-12-31'});

          this.bookingInfoObservable = this.ServiceHandler.getTxnInfo([], params)
      }
}

Snippet from your dashboard template:

<app-summary-chips [lineChart]="lineChart[0]" [value] = "value[0]" [name] = "names[0]" [data] = "bookingInfoObservable"></app-summary-chips>

Code for your child component:

@Component({
  selector: 'app-summary-chips',
  templateUrl: './summary-chips.component.html',
  styleUrls: ['./summary-chips.component.scss']
})
export class SummaryChipsComponent implements OnInit {
  @Input('lineChart') lineChart: string;
  @Input('value') value: string;
  @Input('name') name: string;
  @Input() data: [];
  bookingInfo = [];

  ngOnInit() {

   console.log('line chart: ', this.lineChart);
   this.data.subscribe(
            bookings => {
              this.bookingInfo = bookings.responseObj.txnValues;
              console.log(this.bookingInfo);
          });
  }

}

You can access a working example of this on Stackblitz. Hopefully, this will assist you in resolving your issue.

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

Initiating a GET request to retrieve the file generated by the server

I am currently delving into the Mean stack and have encountered a challenge with downloading a file from my server-side application using the Angular front end. Despite successfully generating the file on the back end, clicking the download button on the f ...

"Discover the process of looping through a collection of IWebElements, storing them in an array, and displaying them in the console using

Currently, I am in the process of learning c# and delving into the world of arrays. As I'm getting hands-on with practical usage of arrays in Selenium c#, I encountered a scenario that posed a challenge - I couldn't figure out how to iterate thro ...

Creating Angular unit test modules

When it comes to creating unit test cases for an Angular app, the application functionality is typically divided into modules based on the requirements. In order to avoid the need for repeated imports in component files, the necessary components, modules, ...

Currently experimenting with implementing malloc functionality in C through functions

Hi there! I'm currently trying to understand why Valgrind is throwing an invalid write of size error at the line: array[i-1] = I; I can't seem to figure out what's wrong with my allocate_array function. I've tried multiple approaches b ...

Is there a way to efficiently insert the data array into 8 tables simultaneously?

I currently have a variable that contains the following array elements $dataRoles = [ 0 => [ 'info1', 'info2', 'info3' ], 1 => [ 'info4', 'info5' ] ] In addition, I have two tabl ...

TypeScript - Variable is inferred to have type 'any' in certain locations where its type cannot be accurately determined

I'm attempting to generate an MD5 hash from the content of an uploaded file. I am trying to set a global declaration to be used within functions, but I encounter an error when trying to utilize it: The error message states - Variable 'hasher&apos ...

Updating dropdown value from a different dropdown selection in Angular 17

I need to set up the form so that selecting Mr in the first dropdown will change the value to male in the second dropdown. Similarly, if Miss/Mrs is selected, the 2nd dropdown should switch to female. Any suggestions on how I can make this work? Here&apo ...

Tips for stopping table column width growth when an icon is inserted into a cell dynamically

In the table I have, the header is clickable and when clicked, it triggers sorting. Clicking on the header title adds an icon (ascending or descending) to the right of the title, causing the column width to increase based on the size of the icon. Refer to ...

Move to the following array when clicking PHP (using Ajax, perhaps?)

How can I trigger php code when a button is clicked? (I understand the distinction between client-side and server-side. However, I believe I have encountered a similar scenario before.) Consider the following array : $test_id = [ 1 => '15 ...

Precisely outline the function type that operates on an object, makes changes to its values, and then outputs the object in TypeScript

Can anyone help me create a function that generates a new object with the same keys as the input object, but with all values set to null? Here's the existing code: function nullify(arg) { var returnObj = {} for (var key in arg) { returnObj[ ...

Provider not found: ConnectionBackend – NullInjectorError

I encountered the following error while attempting to load the webpage. Despite trying various suggestions from other sources, I have been unable to find a solution. Below the error stack lies my code. core.js:7187 ERROR Error: Uncaught (in promise): Null ...

What is the correct approach to managing Sequelize validation errors effectively?

I am working on a basic REST API using Typescript, Koa, and Sequelize. If the client sends an invalid PUT request with empty fields for "title" or "author", it currently returns a 500 error. I would prefer to respond with a '400 Bad Request' ins ...

Angular 4: Triggering Scroll Event when Select Dropdown Reaches End

I am attempting to trigger a Scroll Event within the component class when the end of the dropdown list is reached. I have a large list and initially only load the first 30 records in ngOnInit(). As the user scrolls down, I want to update the dropdown list ...

Issue involving interface implementation (#6634) when transitioning from legacy code to Fortran 90/95

After spending a considerable amount of time working with a scientific software for mechanical analysis, I found myself dealing with code that originated in the eighties (Fortran 77) and has since evolved into a hybrid form of Fortran 90/95. To enhance the ...

Transforming a byte[] BGRA array into a more efficient and faster option (JAVA)

I'm working with a byte[] array that holds BGRA raster data, where each component is represented by a different index in the array (e.g. first byte for blue, second for green). I want to manipulate this data, but I'm curious if there's a Jav ...

The router fails to navigate upon clicking after transitioning from beta to rc5 as a module

My routing configuration is as follows: import { Router, RouterModule } from '@angular/router'; import { HomeComponent } from './modules/home/home.component'; import { Step1Component } from './modules/step1/step1.component' ...

What sets template-driven and reactive forms apart in practice?

Exploring the Angular2 new Forms API has revealed two distinct approaches to forms: Template driven and reactive (model-driven) forms. I am curious about the real-world differences between these two methods, beyond just syntax. Which approach is more adva ...

Angular2 encounters an error when processing a custom HTTP request

I offer two unique services Custom HTTP client service fetch(url):any{ this.storage.fetchData('auth-token').then((token) => { let headers = new Headers(); this.prepareHeaders(headers); return this.http.fetch(url+"?token="+toke ...

Child Route Handling Based on Conditions (Angular)

Can a child route be conditionally displayed as a default? I want users to land on a specific child route based on their past orders (e.g., go to the store page if they ordered from a physical store, online page for online orders, or social page otherwise ...

Performing multiple asynchronous tasks using RxJS by running Array.prototype.map in parallel batches or queues

Imagine having an array of variables, such as: [Sasha, Misha, Caitlyn, ...String] (string[]) with a sizable length of about 10k elements. If you want to run an asynchronous parallel task with these elements, but not all at once like Promise.all, rather in ...