Reputation: 45
I have a drop down list on my parent component and when a user select a value, I want to pass that value to the child to be passed in another method call to the database. The issue is my value in the child is always undefined.
parent HTML
<div>
<div style="margin-bottom: 20px;">
<kendo-label [for]="reportList" text="Report:" style="margin-right: 10px;margin-bottom: 20px;"></kendo-label>
<kendo-dropdownlist #reportList
[data]="reportListData"
[defaultItem]=defaultSelection
textField="reportName"
valueField="url"
(selectionChange)="reportDropDownChange($event)"
width="550px"></kendo-dropdownlist>
</div>
<div>
<kendo-label [for]="usersubscriptionadmin" text="Distributor Admin:" *ngIf="isAdmin()" style="margin-right: 10px;"></kendo-label>
<kendo-combobox #usersubscriptionadmin
[data]="userSubscriptionAdministrators"
[textField]="'userName'"
[valueField]="'userId'"
*ngIf="isAdmin()"
(selectionChange)="userSubscriptionAdminChange($event)"
style="width: 500px;"></kendo-combobox>
</div>
<div style="margin-top: 20px;">
<router-outlet></router-outlet>
</div>
</div>
parent.ts
import { Component, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import {Notifications} from './../core/notifications/notifications';
import {UserService} from './../user/user.service';
import {ReportListModel} from './../user/models/report-list-model';
import { UserSubscriptionAdministratorModel } from '../user/models/user_subscription_administrator_model';
@Component({
selector: 'app-reports-main',
templateUrl: './reports-main.component.html',
styleUrls: ['./reports-main.component.scss']
})
export class ReportsMainComponent implements OnInit {
public reportListData: ReportListModel[] = [{reportName: "Subscription Invoice Summary", url: "reports/invoice-report"},
{reportName: "Subscription Invoice Details", url: "reports/invoice-detail"},
{reportName: "Admin Report", url: "reports/admin-report"}];
public defaultSelection: ReportListModel = {reportName: 'Select a report', url:""};
public userSubscriptionAdministrators: UserSubscriptionAdministratorModel[] = [];
public href: any;
public reportURL: string='';
public selectedAdminUserId: number;
constructor(private notifications: Notifications, private router: Router, private userService: UserService) {
router.events.subscribe((event) =>{event instanceof NavigationEnd? this.href = event: null}); //get the page URL if there is a refresh
}
ngOnInit() {
//if the array is greater than one, then we know the user refreshed the page and already selected a report
//so now set the report drop down
this.reportURL = this.href.url.split('/')[2];
//now set the default report selection to be the page URL
if(this.reportURL != undefined)
{
console.log('setting default selection');
this.defaultSelection = this.reportListData.find(x => x.url.includes(this.reportURL));
}
this.userService.GetUserSubscriptionAdministrators().subscribe(response => {
response.forEach(a => {
let admin = new UserSubscriptionAdministratorModel();
admin.subscriptionId = a.subscriptionId;
admin.userId = a.userId;
admin.userName = a.firstName + ' ' + a.lastName;
if (a.customerName !== null) {
admin.userName += ' - ' + a.customerName;
}
if (a.ctsid !== 0) {
admin.userName += ' (' + a.ctsid + ')';
}
this.userSubscriptionAdministrators.push(admin);
});
})
}
public reportDropDownChange($event)
{
if($event.url != ""){
this.router.navigate([$event.url]);
}
}
public isAdmin() {
if (sessionStorage.getItem("UserType") == 'Administrator') {
return true;
} else {
return false;
}
}
public userSubscriptionAdminChange($event){
console.log('Parent value change ' + $event.userId);
this.selectedAdminUserId = $event.userId;
}
}
Child HTML
form [formGroup]="form" class="k-form-horizontal">
<div style="display: inline-block;">
<div style="display: inline-block; width: 175px;">
<kendo-label [for]="fromDate" text="From:" style="padding-right: 6px;"></kendo-label>
<kendo-datepicker
calendarType="classic"
formControlName="fromDate"
format="MM/yyyy"
placeholder="MM/YYYY"
#fromDate
style="width: 125px;">
</kendo-datepicker>
</div>
<div style="display: inline-block; width: 175px;">
<kendo-label [for]="toDate" text="To:" style="padding-right: 6px;"></kendo-label>
<kendo-datepicker
calendarType="classic"
formControlName="toDate"
format="MM/yyyy"
placeholder="MM/YYYY"
#toDate
style="width: 125px;">
</kendo-datepicker>
</div>
<div style="display: inline-block; width: 200px;">
<kendo-label [for]="txtInvoiceNumber" text="Invoice Number:" style="padding-right: 6px;"></kendo-label>
<kendo-textbox #txtInvoiceNumber formControlName="txtInvoiceNumber" style="width: 200px;"></kendo-textbox>
</div>
<div style="display: inline-block; width: 150px;padding-left: 6px;">
<button type="submit" class="k-button k-primary" (click)="RunReport()" >Search</button>
</div>
</div>
<div style="display: inline-block; padding-top: 5px;">
<kendo-grid
[data]="gridData"
[resizable]="true"
filterable="menu"
[sortable]="true"
[filter]="state.filter"
[skip]="state.skip"
[sort]="state.sort"
[pageSize]="state.take"
[pageable]="true"
[height]="375" >
<ng-template kendoGridToolbarTemplate>
<button type="button" kendoGridExcelCommand icon="file-excel">Export to Excel</button>
</ng-template>
<kendo-grid-column field="invoiceDate" title="Date" width="100"></kendo-grid-column>
<kendo-grid-column field="poNumber" title="PO Number" width="100"></kendo-grid-column>
<kendo-grid-column field="invoiceNumber" title="Invoice Number" width="100"></kendo-grid-column>
<kendo-grid-column field="invoiceAmount" title="Amount" width="100" format="{0:c}"></kendo-grid-column>
<kendo-grid-excel fileName="InvoiceSummaryReport.xlsx" [fetchData]="excelExportData">
<kendo-excelexport-column field="invoiceDate" title="Date"></kendo-excelexport-column>
<kendo-excelexport-column field="ponumber" title="PO Number"></kendo-excelexport-column>
<kendo-excelexport-column field="invoiceNumber" title="Invoice Number"></kendo-excelexport-column>
<kendo-excelexport-column field="invoiceAmount" title="Amount"></kendo-excelexport-column>
</kendo-grid-excel>
</kendo-grid>
</div>
</form>
childcomponent.ts
import { Component, Input, OnInit, } from '@angular/core';
import {FormControl, FormGroup} from '@angular/forms';
import {Router} from '@angular/router';
import {DatePipe} from '@angular/common';
import {addYears} from '@progress/kendo-date-math';
import {State, process} from '@progress/kendo-data-query'
import { ExcelExportData } from '@progress/kendo-angular-excel-export'
import {InvoiceSummaryReportModel} from '../models/invoice-summary-model';
import {ReportService} from '../report.service';
import { InvoiceSummarySearchModel } from '../models/invoice-summary-search-model';
import { Notifications } from '../../core/notifications/notifications';
@Component({
selector: 'app-invoice-report',
templateUrl: './invoice-report.component.html',
styleUrls: ['./invoice-report.component.css']
})
export class InvoiceReportComponent implements OnInit {
@Input('selectedAdminUserId') public parentSelectedAdminUserId: any;
public form: FormGroup;
public exportState: State;
public gridData: InvoiceSummaryReportModel[];
public exportData: any;
public tempDate:any;
public userId: number = Number(sessionStorage.getItem('UserId'));
public invoiceSearch: InvoiceSummarySearchModel;
public href: any;
public state: State = {
take: 20
}
constructor(private reportService: ReportService,
private router: Router,
private datepipe: DatePipe,
private notifications: Notifications) {
this.form = new FormGroup ({
fromDate: new FormControl(addYears(new Date(), -1)),
toDate: new FormControl(new Date()),
txtInvoiceNumber: new FormControl()
});
this.excelExportData = this.excelExportData.bind(this);
}
ngOnInit() { }
public RunReport(){
this.invoiceSearch = new InvoiceSummarySearchModel();
console.log('parent user id ' + this.parentSelectedAdminUserId);
if(this.isAdmin())
{
this.invoiceSearch.userId = this.parentSelectedAdminUserId;
}
else
{
this.invoiceSearch.userId = this.userId;
}
this.tempDate = this.datepipe.transform(this.form.controls.fromDate.value, 'MM/dd/yyyy').split("/");
this.invoiceSearch.fromDateMonth = parseInt(this.tempDate[0]);
this.invoiceSearch.fromDateYear = parseInt(this.tempDate[2]);
this.tempDate = this.datepipe.transform(this.form.controls.toDate.value, "MM/dd/yyyy").split("/");
this.invoiceSearch.toDateMonth = parseInt(this.tempDate[0]);
this.invoiceSearch.toDateYear = parseInt(this.tempDate[2]);
this.invoiceSearch.invoiceNumber = this.form.controls.txtInvoiceNumber.value;
this.reportService.GetInvoiceSummaryReport(this.invoiceSearch).subscribe(response => {
if(response.message == "Success"){
this.gridData = response.result;
}
else{
this.notifications.error(response.message);
}
});
}
public excelExportData(): ExcelExportData {
//set a filter for export if the user has filtered the result set.
this.exportState = {
filter: this.state.filter
};
//now set all the data to be exported. Using gridData will only return the first page because the array is spliced to into 20 records.
this.exportData = process<InvoiceSummaryReportModel>(this.gridData, this.exportState)
const result: ExcelExportData = {
data: this.exportData.data
};
return result;
}
isAdmin() {
if (sessionStorage.getItem("UserType") == 'Administrator') {
return true;
} else {
return false;
}
}
}
How do I set the parentSelectedAdminUserId
in the child component?
Upvotes: 0
Views: 774
Reputation: 31105
You aren't showing how the RunReport()
function in the child component is triggered. But generally I could see the @Input
variable is not being accessed dynamically. You could do one of the following
@Input
as a setterChild component
export class InvoiceReportComponent implements OnInit {
@Input() set parentSelectedAdminUserId(value: any) {
console.log('parent user id:', value);
// do something else
}
}
ngOnChanges
hookChild component
import { Component, OnInit, OnChanges, SimpleChanges, Input } from '@angular/core';
export class InvoiceReportComponent implements OnInit, OnChanges {
@Input() parentSelectedAdminUserId: any
ngOnChanges(changes: SimpleChanges) {
if (
!!changes &&
!!changes.parentSelectedAdminUserId &&
!!changes.parentSelectedAdminUserId.currentValue
) {
console.log('parent user id:', this.parentSelectedAdminUserId);
// do something else
}
}
}
Upvotes: 1
Reputation: 9145
Let's say the selector of your InvoiceReportComponent
is invoice-report
. Then, in the html of the parent component, you should pass that property like this:
<invoice-report [parentSelectedAdminUserId]="selectedAdminUserId" />
Upvotes: 0