Mat-Table from angular materials not displaying data from firebase - javascript

I'm using Angular, NgRedux and firebase (real time database). I'm trying to display my fetched data into a mat-table from Angular/material. I can see the data in the console, but not in the table. I can only display my local data in the table as you can see in my events.component.html temple down bellow.
I'm quite new with Angular. Any help will be highly appreciated.
here is my events.component.ts file
import { NgRedux } from '#angular-redux/store';
import { Component, OnInit } from '#angular/core';
import { MatTableDataSource } from '#angular/material/table';
import { Router } from '#angular/router';
import { Event } from '../entities/Event';
import { EventeActions } from '../store/actions/EventAcitons';
import { AppState } from '../store/Store';
#Component({
selector: 'app-events',
templateUrl: './events.component.html',
styleUrls: ['./events.component.scss']
})
export class EventsComponent implements OnInit{
public events: Event[];
private availableEvents: Event[] = [
{
event: 'Picnic',
date: '12/02/2021',
location: 'Rådhusstrædet',
status: 'published'
},
{
event: 'Surfing',
date: '11/04/2021',
location: 'København V',
status : 'draft'
},
];
displayedColums = ['event', 'date', 'location', 'status'];
dataSource = new MatTableDataSource<Event>();
getAvailableEvents() {
return this.availableEvents.slice();
}
constructor(
private router: Router,
private ngRedux: NgRedux<AppState>,
private eventActions: EventeActions
) { }
ngOnInit(): void {
this.eventActions.readEvent();
// this.dataSource.data = this.getAvailableEvents();
this.ngRedux.select(state => state.events).subscribe(res => {
this.events = res.events;
})
}
editPost(id: any) {
this.router.navigate(['neweditevent', {myId: id}])
}
}
and here is my events.component.html file
<h1 class="title">Planned Events</h1>
<div class="flexHeader">
<button mat-raised-button color="primary" routerLink="/neweditevent" id="newEditBtn">New Event</button>
</div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container matColumnDef="event">
<th mat-header-cell *matHeaderCellDef> Event </th>
<td mat-cell *matCellDef="let element"> {{element.event}} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef> Date </th>
<td mat-cell *matCellDef="let element"> {{element.date | date}} </td>
</ng-container>
<ng-container matColumnDef="location">
<th mat-header-cell *matHeaderCellDef> Location </th>
<td mat-cell *matCellDef="let element"> {{element.location}} </td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef> Status </th>
<td mat-cell *matCellDef="let element"> {{element.status}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColums"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColums;"></tr>
</table>
Thank you in advance...

Try something like this
ngOnInit(): void {
this.eventActions.readEvent();
// this.dataSource.data = this.getAvailableEvents();
this.ngRedux.select(state => state.events).subscribe(res => {
this.events = res.events;
this.dataSource.data = this.events;
})
}

Related

How to access data souce Angular Material Table

I hope everyone is doing great. Im trying to render data to the table for a material table but I cant solve why it isnt working. When I want to assign the data to the datasource for the table to render it dosnt get the information. Would apprecaite if someone could look for a secound and see if something.
Typescript and HTML:
import { Component, OnInit, ViewChild } from '#angular/core';
import { Nobina2NewsesService, StopInfoApiApplicationQueriesNobina2NewsesNobina2NewsResponse } from '../../services/mssql/stop/api/v1';
import { MatPaginator } from '#angular/material/paginator';
import { MatSort } from '#angular/material/sort';
import { MatTableDataSource } from '#angular/material/table';
#Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
news_list: any;
user_list: any;
data: any;
displayedColumns: string[] = ['id', 'title', 'date', 'text'];
dataSource: MatTableDataSource<StopInfoApiApplicationQueriesNobina2NewsesNobina2NewsResponse>;
#ViewChild(MatPaginator)
paginator!: MatPaginator;
#ViewChild(MatSort)
sort!: MatSort;
newsListService = this.newsService.v1Nobina2NewsesGet().subscribe(
(res) => {
this.news_list = res;
},
(err) => { console.log(err); alert("Kolla nätverksanslutnignen(CORS)"); },
() => console.log('done a lot with news!')
);
constructor(private newsService: Nobina2NewsesService) {
// Assign the data to the data source for the table to render
this.dataSource = new MatTableDataSource(this.news_list);
}
ngOnInit(): void {
throw new Error('Method not implemented.');
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
}
<mat-form-field appearance="standard">
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Filter" #input>
</mat-form-field>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<td mat-cell *matCellDef="let news"> {{ news.id }} </td>
</ng-container>
<!-- Progress Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Titel </th>
<td mat-cell *matCellDef="let news"> {{news.title}}% </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Datum </th>
<td mat-cell *matCellDef="let news"> {{ news.date.split('T')[0] }} </td>
</ng-container>
<!-- Fruit Column -->
<ng-container matColumnDef="text">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Text </th>
<td mat-cell *matCellDef="let news"> {{news.text}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let news; columns: displayedColumns;"></tr>
<!-- Row shown when there is no matching data. -->
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
</tr>
</table>
<mat-paginator [pageSizeOptions]="[10, 25, 100]" aria-label="Select page of news"></mat-paginator>
</div>
It may be that when you assign the value to the dataSource the variable new_list has no value, try this way:
constructor(private newsService: Nobina2NewsesService) {
this.getData();
}
getData(): void {
this.newsService.v1Nobina2NewsesGet().subscribe(res => {
this.new_list = res;
this.setDataSource();
}, err => {
console.log(err); alert("Kolla nätverksanslutnignen(CORS)");
});
}
setDataSource(): void {
this.dataSource = new MatTableDataSource(this.news_list);
}

Error: Cannot find control with path of arrayname => formarray inside mat table in angular8?

HTML:(Here I have a table with formArray.I want to patch Value When I select the Value from Pomaterials array.It is there bottom of the table. but When i select the item, its throwing error,cannot find control with path.I have tried formControls instead of datasource, still its giving same error. can you help me?)
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" formArrayName="receive_mat">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; let index = index; columns:displayedColumns;"
[formGroupName]="index"></tr>
<ng-container matColumnDef="material">
<th mat-header-cell *matHeaderCellDef>Material</th>
<td mat-cell *matCellDef="let element">
<mat-form-field floatLabel="never" style="width: 76px">
<input matInput type="text" formControlName="material" readonly/>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="qty_receiving">
<th mat-header-cell *matHeaderCellDef>Qty Receiving</th>
<td mat-cell *matCellDef="let element">
<mat-form-field floatLabel="never" style="width: 76px">
<input matInput type="number" formControlName="quantityreceiving">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="best_before">
<th mat-header-cell *matHeaderCellDef>Best Before</th>
<td mat-cell *matCellDef="let element">
<mat-form-field style="width: 80px">
<mat-label>Best Before</mat-label>
<input matInput [matDatepicker]="picker" formControlName="bestbefore" readonly/>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker disabled="false"></mat-datepicker>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
Delete<mat-icon (click)="removeElement(element, index)">cancel</mat-icon>
</td>
</ng-container>
</table>
<!-- <button>add</button> -->
<mat-form-field style="width:100px;margin-left:10px;">
<mat-select placeholder="Select Material" [(value)]="data"
(selectionChange)="selectedItem(data)" >
<mat-option *ngFor="let item of poMaterials" [value]="item">{{item.material_id.title}}</mat-option>
</mat-select>
</mat-form-field>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons></mat-paginator>
</div>
component.ts:
ngOnInit(){
this.receiveForm = new FormGroup({
'receive_mat': new FormArray([]),
})
this.receive_mat = this.receiveForm.get('receive_mat') as FormArray;
this.dataSource = new MatTableDataSource((this.receiveForm.get('receive_mat') as FormArray).controls);
}
selectedItem(item){
console.log(item)
this.dataSource = new MatTableDataSource((this.receiveForm.get('receive_mat') as FormArray).controls);
this.addItem(item)
}
createItem(item): FormGroup {
console.log(item)
return this._formBuilder.group({
'material': new FormControl(item.material_id.title, Validators.required),
'quantityreceiving': new FormControl(null, Validators.required),
'bestbefore': new FormControl(new Date()),
})
}
addItem(item){
console.log(item)
this.receive_mat.push(this.createItem(item))
}
You need to get the reference of the form array and then push the item to it. Here is an example.
import { Component,OnInit, VERSION } from '#angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit{
name = 'Angular ' + VERSION.major;
form: FormGroup;
items: FormArray;
constructor(
private formBuilder: FormBuilder
) {}
ngOnInit(): void {
this.form = this.formBuilder.group({
items: this.formBuilder.array([])
});
}
addItem(): void {
this.items = this.form.get('items') as FormArray;
this.items.push(this.createItem());
}
createItem(): FormGroup {
return this.formBuilder.group({
'material': new FormControl(item.material_id.title, Validators.required),
'quantityreceiving': new FormControl(null, Validators.required),
'bestbefore': new FormControl(new Date())
});
}
}

Why I can't get result from parent component in Angular

I want child components in angular to separate Material Table(child) from other elements(parent), but the weird thing is that it seems I cannot get data from the parent or I get initialized data from parents and cannot refresh.
Here is the Code:
firstly, the parent .ts file:
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit{
ticketList: Ticket[] = [];
originalTicketList: Ticket[] = [];
filterAllForm: FormGroup;
labelList: string[];
homeLabelList: string[];
currentTicketId: string;
searchBy: string = '';
maxall : number = 100;
isLoading :boolean = true;
showRelatedTickets = true;
constructor(private ticket: TicketService,
private formBuilder: FormBuilder) { }
ngOnInit() {
this.filterAllForm = this.formBuilder.group({
startDate: [''],
endDate: ['']
});
this.getAllTicket();
}
get filterFormControls() { return this.filterAllForm.controls; }
getAllTicket() {
let queryParams = '';
console.log(this.currentTicketId) + " " + this.searchBy;
if (this.searchBy === 'id') {
queryParams = 'id=' + this.currentTicketId;
this.showRelatedTickets = true;
}else if(this.searchBy !== ''){
queryParams = this.searchBy + '=' + this.currentTicketId;
this.showRelatedTickets = false;
}
this.ticket.getAllTicket(queryParams).then((res: Ticket[]) => {
this.isLoading = false;
this.ticketList = res;
this.originalTicketList = this.ticketList;
});
}
searchTicket() {
this.isLoading = true;
this.getAllTicket();
}
}
the parent html like this:
<div class="ticket-container">
<mat-card *ngIf="isLoading" class="mat-card-style">
<mat-progress-spinner color="primary" mode="indeterminate">
</mat-progress-spinner>
</mat-card>
<div *ngIf="showRelatedTickets">
<app-dashboard-related-tickets-table [tablesource]="ticketList">
</app-dashboard-related-tickets-table>
</div>
<div *ngIf="!showRelatedTickets">
<app-dashboard-non-related-tickets-table [tablesource]="ticketList">
</app-dashboard-non-related-tickets-table>
</div>
</div>
and there are two children you can see, one is app-dashboard-related-tickets-table and another one is app-dashboard-non-related-tickets-table, they have a different format and changed by the button
showRelatedTickets. Here I will show the first one
the child(app-dashboard-related-tickets-table) .ts file:
#Component({
selector: 'app-dashboard-related-tickets-table',
templateUrl: './dashboard-related-tickets-table.component.html',
styleUrls: ['./dashboard-related-tickets-table.component.scss']
})
export class DashboardRelatedTicketsTableComponent implements OnInit, AfterViewInit{
dataSource: any;
displayedDetailColumns = ['id', 'caseStatus', 'anchorPoint', 'findingSourceSystem','caseCreateTimestamp', 'resolvedBy', 'resolution', 'resolutionNote'];
maxall: number = 100;
#Input() tablesource: Ticket[];
#ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
#ViewChild(MatSort, { static: true }) sort: MatSort;
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
constructor() { }
ngOnInit() {
console.log(this.tablesource);
this.dataSource = new MatTableDataSource(this.tablesource);
}
ngAfterViewInit(){
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.getPageSizeOptions();
}
getPageSizeOptions(): number[] {
if (this.dataSource.data.length>this.maxall){
return [20, 50, this.dataSource.data.length];
}else{
return [20, 50, this.maxall];
}
}
}
then the child(app-dashboard-related-tickets-table) .html file:
<table mat-table matTableExporter [dataSource]="dataSource" matSort class="mat-elevation-z8"
#exporter="matTableExporter">
<!-- Ticket Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-id-source"> SIR ID </th>
<td mat-cell *matCellDef="let element" class="mat-column-id-source">
<a href='ticket/{{element.id}}'>{{element.id}}</a>
</td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="findingSourceSystem">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-id-source"> Source </th>
<td mat-cell *matCellDef="let element" class="mat-column-id-source"> {{element.findingSourceSystem}} </td>
</ng-container>
<!-- Type Column Related Event count -->
<ng-container matColumnDef="anchorPoint">
<th mat-header-cell *matHeaderCellDef class="mat-column-related-ticket-num"> Related Cases </th>
<td mat-cell *matCellDef="let element" class="mat-column-related-ticket-num">
{{element.relatedVertices}} </td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="caseStatus">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-case"> Case Status </th>
<td mat-cell *matCellDef="let element" class="mat-column-case"> {{element.caseStatus}} </td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="caseCreateTimestamp">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-date"> Case Created </th>
<td mat-cell *matCellDef="let element" class="mat-column-date">
{{element.caseCreateTimestamp | date:'MMM d, y, h:mm:ss a'}}
</td>
</ng-container>
<ng-container matColumnDef="resolvedBy">
<th mat-header-cell *matHeaderCellDef class="mat-column-resolvedBy"> Resolved By </th>
<td mat-cell *matCellDef="let element" class="mat-column-resolvedBy"> {{element.resolvedBy}}
</td>
</ng-container>
<ng-container matColumnDef="resolution">
<th mat-header-cell *matHeaderCellDef class="mat-column-closeCode"> Close Code </th>
<td mat-cell *matCellDef="let element" class="mat-column-closeCode"> {{element.resolution}}
</td>
</ng-container>
<ng-container matColumnDef="resolutionNote">
<th mat-header-cell *matHeaderCellDef class="mat-column-closeNote"> Close Note </th>
<td mat-cell *matCellDef="let element" class="mat-column-closeNote"> {{element.resolutionNote}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="getPageSizeOptions()" showFirstLastButtons></mat-paginator>
<button mat-raised-button (click)="exporter.exportTable('csv')" class="export-button">Export Results</button>
So in the child component, I use #input tablesource, and display dataSource. but the result is like this:
The child component seems loaded because the export result button is already there, but the table didn't show. I just to do
console.log(tablesource)
I got []
This is the browser console log:
Any Idea what happened?
I was trying to reproduce here: https://stackblitz.com/edit/angular-hbzpvr
but I am sorry, I am not good at angular, so I am not sure how to load parent to page.
According to your console output, you use tablesource in your child component before it has been updated by the parent component. Instead of creating datasource in ngOnInit of the child component, define the tablesource property as a setter and create datasource in that setter:
#Input() set tablesource(value: Ticket[]) {
console.log(value);
this.dataSource = new MatTableDataSource(value);
}
See this stackblitz for a demo.

How to display or split a single string one below another inside a <td>

i have data in in a td similar to
Sugar:5;Onion:3;Carrot:9;Bread:9;
where i want to display like,
Sugar:5
Onion:3
Carrot:9
Bread:9
Inside a td in a table.
im trying to implement using angular material table
i have reached only this much, want to achieve like the above image for Items column
code:
html file
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<ng-container matColumnDef="orderId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> orderId </th>
<td mat-cell *matCellDef="let element"> {{element.orderId}} </td>
</ng-container>
<ng-container matColumnDef="customerId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> customerId </th>
<td mat-cell *matCellDef="let element"> {{element.customerId}} </td>
</ng-container>
<ng-container matColumnDef="deliveryPincode">
<th mat-header-cell *matHeaderCellDef mat-sort-header> deliveryPincode </th>
<td mat-cell *matCellDef="let element"> {{element.deliveryPincode}} </td>
</ng-container>
<ng-container matColumnDef="orderDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header> orderDate </th>
<td mat-cell *matCellDef="let element"> {{element.orderDate}} </td>
</ng-container>
<ng-container matColumnDef="items">
<th mat-header-cell *matHeaderCellDef mat-sort-header> items </th>
<td mat-cell *matCellDef="let element"> {{element.items}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
Upload
typescriptfile
import {MatSort} from '#angular/material/sort';
import {MatTableDataSource} from '#angular/material/table';
import * as XLSX from 'xlsx';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'antstack-problem';
arrayBuffer:any;
file:File;
displayedColumns: string[] = ['orderId', 'customerId', 'deliveryPincode','orderDate', 'items' ];
dataSource = new MatTableDataSource();
#ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
this.dataSource.sort = this.sort;
}
incomingfile(event) {
this.file= event.target.files[0];
}
Upload() {
let fileReader = new FileReader();
fileReader.onload = (e) => {
this.arrayBuffer = fileReader.result;
var data = new Uint8Array(this.arrayBuffer);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
var workbook = XLSX.read(bstr, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var worksheet = workbook.Sheets[first_sheet_name];
this.dataSource = new MatTableDataSource(XLSX.utils.sheet_to_json(worksheet,{raw:true}));
this.dataSource.sort = this.sort;
console.log(XLSX.utils.sheet_to_json(worksheet,{raw:true}));
}
fileReader.readAsArrayBuffer(this.file);
}
}
I would go for a Map() and ngFor, which gives you some stuff like this:
<ul>
<li *ngFor="let recipient of map | keyvalue">
{{recipient.key}} --> {{recipient.value}}
</li>
</ul>
https://stackblitz.com/edit/angular-map-keyvalue
(seen here)
You can wrap the items in the p tag. This will also break this in the next line.

Accessing Input fields inside Angular Material table

I've been trying for days to get data from input fields inside an Angular Material Table.
I am basically populating a table with values that come from an API, however whenever we don't get any date, in my case a course doesn't have a scheduled date set, i am inserting a text box where the value should be displayed so the user can set a date for that specific course.
Like this:
Note: Sorry for the censoring, work related names had to be removed.
This is my html code:
<mat-card>
<form #traineeForm="ngForm">
<mat-form-field>
<input readonly matInput type="text" name="name" [ngModel] = "trainee.name" #name="ngModel">
</mat-form-field>
<mat-form-field>
<input readonly matInput email type="text" name="email" [ngModel] = "trainee.email" #email="ngModel">
</mat-form-field>
<mat-form-field>
<input readonly matInput type="text" name="type" [ngModel] = "trainee.type" #type="ngModel">
</mat-form-field>
<button mat-raised-button color ="primary" type ="submit">Edit</button>
<button mat-raised-button color ="warn" type ="submit" (click)="onDelete(trainee.id)">Delete</button>
</form>
</mat-card>
<br>
<mat-card>
<table mat-table [dataSource]="courses" class="mat-elevation-z8">
<ng-container matColumnDef="courseOrderID">
<th mat-header-cell *matHeaderCellDef>Course Order ID</th>
<td mat-cell *matCellDef="let element"> {{element.courseOrderID}}</td>
</ng-container>
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>Course Title </th>
<td mat-cell *matCellDef="let element"> {{element.title}}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>Course Description </th>
<td mat-cell *matCellDef="let element"> {{element.description}}</td>
</ng-container>
<ng-container matColumnDef="duration">
<th mat-header-cell *matHeaderCellDef>Duration </th>
<td mat-cell *matCellDef="let element"> {{element.duration}}</td>
</ng-container>
<ng-container matColumnDef="scheduledDate">
<th mat-header-cell *matHeaderCellDef>Scheduled Date </th>
<td mat-cell *matCellDef="let element">
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
{{element.scheduledDate}}</td>
</ng-container>
<ng-container matColumnDef="trainer">
<th mat-header-cell *matHeaderCellDef>Trainer </th>
<td mat-cell *matCellDef="let element">
<mat-form-field><input matInput color="warn" *ngIf="!element.trainer"></mat-form-field> {{element.trainer}}</td>
</ng-container>
<ng-container matColumnDef="save">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<button mat-raised-button color ="primary" type ="submit" (click)="onSaveAssignment(trainee, element, picker)">Save</button></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="coursesdisplayColumns">
</tr>
<tr mat-row *matRowDef="let courses; columns: coursesdisplayColumns"></tr>
</table>
<br>
</mat-card>
And this is my TypeScript code:
import { Trainee } from '../trainees.model';
import { Component, OnInit, OnDestroy } from '#angular/core';
import { Subscription } from 'rxjs';
import { TraineesService } from '../../trainees.service';
import { ActivatedRoute, ParamMap } from '#angular/router';
import { Course } from '../../courses/courses.model';
import { CoursesService } from '../../courses.service';
import { Assignment } from '../../assignments/assignments.model';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-trainee-details',
templateUrl: './trainee-details.component.html',
styleUrls: ['./trainee-details.component.css']
})
export class TraineeDetailsComponent implements OnInit, OnDestroy {
private traineeId: string;
trainee: Trainee;
assignment: Assignment;
courses: Course[] = [];
coursesdisplayColumns = ['courseOrderID', 'title','description','duration','scheduledDate','trainer','save'];
constructor(public traineeService: TraineesService, public route: ActivatedRoute, public coursesService: CoursesService){}
ngOnInit() {
this.route.paramMap.subscribe((paramMap: ParamMap) => {
if(paramMap.has('traineeId')){
this.traineeId = paramMap.get('traineeId');
this.trainee = this.traineeService.getTrainee(this.traineeId);
}
});
this.coursesService.getCoursesByJob(this.trainee.job);
this.coursesService.getCoursesUpdateListener().subscribe((courses: Course[]) =>{
this.courses = courses;
});
}
onDelete(traineeId: string)
{
this.traineeService.deleteTrainee(traineeId);
}
onSaveAssignment(trainee: Trainee, selectedCourse: Course, dateForm: Date){
console.log(trainee.id);
console.log(selectedCourse.description);
console.log(dateForm);
}
ngOnDestroy() {
}
}
When i call onSaveAssignment(), the trainee ID and course ID are getting logged in the console correctly as those are defined in typescript, but I have no ideea how should i bring that date selected in the interface, i tried with ng-model but it did not work and I had to define a form for each input and still did not work.
Is there any way to get that values from inputs on each row when the Save button is pressed ?
Or if i put 1 button for all of them is there any way to do a foreach on every input value in the interface ?
You can get the values with ngModel by creating an object containing all values using the index as attribute.
In you component, put an object:
public myDates : any = {};
Then use ngModel with the index for your input date:
<ng-container matColumnDef="scheduledDate">
<th mat-header-cell *matHeaderCellDef>Scheduled Date </th>
<td mat-cell *matCellDef="let element; let i = index">
<mat-form-field>
<input matInput [(ngModel)]="myDates[i]" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</td>
</ng-container>
For each row, it will add an attribute to the object myDates. Using index permits to guarantee uniqueness. Your object will look like: {1: date1, 2: date2 ...}.
Then you can get the value by knowing the index of the row.
You can get it directly when clicking on the button:
<ng-container matColumnDef="save">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element; let i = index">
<button mat-raised-button color ="primary" type ="submit" (click)="onSaveAssignment(trainee, element, myDates[i])">Save</button>
</td>
</ng-container>

Categories

Resources