How to access specific object in JSON using Angular? - html

I'm trying to access certain data from an API and having trouble doing so. Here is the structure of the JSON from the API:
I'm wanting to access Name, StateName & CityName within value to iterate through a table. I'm getting the obvious error "Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays", because ngFor isn't iterating through the array. How can I fix my code to iterate through the data to fill my table?
component.ts:
#Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
customer: any;
constructor(private Service: CustomerDataService) { }
ngOnInit(): void {
this.getCustomerData();
}
public getCustomerData() {
this.Service.getCustomers().subscribe((data)=>{
console.log(data);
this.customer = data;
})
}
}
HTML:
<div class="container">
<form class="form-inline">
<div class="input-group mb-2">
<div class="has-clear">
<input type="text" name="search" required class="form-control" placeholder="Name" />
<button class="clear-data" type="reset"><i class="icon-close-bold-sm"></i></button>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-3">Search</button>
</div>
</form>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">City</th>
<th scope="col">State</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let customers of customer">
<td scope="row">{{customers.value.Name}}</td>
<td scope="row">{{customers.value.StateName}}</td>
<td scope="row">{{customers.value.CityName}}</td>
</tr>
</tbody>
</table>
</div>
</div>

The value is an array and not object, so
public getCustomerData() {
this.Service.getCustomers().subscribe((data)=>{
console.log(data);
this.customer = data.value;
})
}
and in your template
<tr *ngFor = "let customers of customer">
<td scope="row">{{customers.Name}}</td>
<td scope="row">{{customers.StateName}}</td>
<td scope="row">{{customers.CityName}}</td>
</tr>
Or you can just edit your template
<tr *ngFor = "let customers of customer.value">
<td scope="row">{{customers.Name}}</td>
<td scope="row">{{customers.StateName}}</td>
<td scope="row">{{customers.CityName}}</td>
</tr>

Consider using | async to access the observable directly in your html
<tr *ngFor = "let customer of customers$ | async">
<td scope="row">{{customer.Name}}</td>
<td scope="row">{{customer.StateName}}</td>
<td scope="row">{{customer.CityName}}</td>
</tr>
and in your component
customers$ : Observable<Customer> = this.getCustomerData();
You can update your getCustomerData with a map operator to return the list of Customers you have inside value property.

Related

Is `teams` word a reserved word in angular?

I have a very puzzling problem. I have in my component a variable teams defined like this:
import { DateFunctionTeams } from '../_models/teams';
import { User } from '../_models/user';
import { AccountService } from '../_services';
import { first } from 'rxjs/operators';
#Component({
selector: 'app-raport-test',
templateUrl: './raport-for-date.component.html',
styleUrls: ['./raport-for-date.component.less']
})
export class RaportForDateComponent implements OnInit {
teams: Team[] = [];
...
}
The relevant part of my HTML looks like this:
<fieldset *ngFor="let team of teams">
<legend>{{team.function}} Users:</legend>
<div class="border border-primary">
<table id=scheduledTable class="table table-striped">
<thead>
<tr>
<th style="width:30%">Function</th>
<th style="width:30%">User</th>
<!--th style="width:30%">UserAvailability</th-->
<th style="width:10%"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of team.users">
<td>{{user.function}} </td>
<td>{{user.firstName}} </td>
</tr>
</tbody>
</table>
</div>
</fieldset>
The line with fieldset *ngFor="let team of teams" in HTML causes the error Type 'HTMLSelectElement' is not assignable to type 'NgIterable<any>'.
Interesting bit is that if I change the name teams to something else (e.g. tms) it works just fine.
Any help appreciated.

how to ExportExcel data with angular typescript

in my project i have a table with information (FirstName, LastName, PhoneNumbre, Age, Date). i create an function making me to export file excel but i don't want to export all the data i need just to export (FirstName, LastName, Age).
this is what i do
excel.html :
<div class="panel-body table-responsive">
<table id="excel-table" class="table">
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>PhoneNumber</th>
<th>Age</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.PhoneNumber}}</td>
<td>{{excel.Age}}</td>
<td>{{excel.Date}}</td>
<td>
<button (click)="exportexcel()">ExportExcel</button>
</td>
</tr>
</tbody>
</table>
</div>
excel.ts :
#Component({
selector: 'app-execls',
templateUrl: './execls.component.html',
styleUrls: ['./execls.component.css']
})
export class RegionsComponent implements OnInit {
constructor(private modalService: NgbModal, private fb: FormBuilder, private toastr: ToastrService) { }
fileName = 'ExcelFile.xlsx';
exportexcel(): void {
let element = document.getElementById('excel-table');
const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(element);
const wb: XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
XLSX.writeFile(wb, this.fileName);
}
So I believe you are using sheetJS based on your code, and looking at the documentation, there is not a way to pass in columns you wish to display. https://docs.sheetjs.com/docs/api/utilities/#html-table-input. One option is to create another table with just the columns you want to display, but set that table to hidden.
<table id="excel-table-to-export" class="table" hidden>
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.Age}}</td>
</tr>
</tbody>
</table>

How to change boolean value within json file using a button in angular & typescript?

My question is, how do I write a function in my table-viewer.component.ts file to change the value from false to true within the JSON file based on whether the user clicks the cancelled button?
I have a JSON file containing the following details.
db.json
"firstName": "Hamza",
"lastName": "Gallagher",
"carReg": "FG67 POI",
"parkingNumber": "00003",
"date": "2021-01-04",
"cancelled": false
etc ..
And I am displaying them in a table with angular, which shows the following:
Image of table
Table-viewer.component.html
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Car Registration</th>
<th>Parking Number</th>
<th>Date</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let booking of bookings">
<td>{{booking.firstName}}</td>
<td>{{booking.lastName}}</td>
<td>{{booking.carReg}}</td>
<td>{{booking.parkingNumber}}</td>
<td>{{booking.date}}</td>
<td>
<div *ngIf="booking.cancelled" class="red">Cancelled</div>
<div *ngIf="!booking.cancelled" class="green">Booked</div>
</td>
<td>
<button class="btn btn-danger mr-2" (click)="cancelBooking()">Cancel</button>
</td>
</tr>
table-viewer.component.ts
export class TableViewerComponent implements OnInit {
bookings: Booking[] = [];
getBookings(): void {
this.bookingService.getAll().subscribe((book: Booking[]) => {
this.bookings = book;
});
}
constructor(private bookingService: BookingService) {
}
ngOnInit(): void {
this.getBookings();
}
cancelBooking(): void {
// Help
}
}
booking.ts
export interface Booking {
'firstName': string;
'lastName': string;
'carReg': string;
'parkingNumber': string;
'date': string;
'cancelled': boolean;
}
I think it is as simple as:
cancelBooking(booking:Booking){
booking.cancelled = true;
}
And just pass it in the view to the method
Please use this code in your componenet.ts
cancelBooking(index): void {
// Help
this.bookings[index].cancelled = true;
}
Template :
Change the loop code with below code:
<tr *ngFor="let booking of bookings; let i = index">
<td>{{booking.firstName}}</td>
<td>{{booking.lastName}}</td>
<td>{{booking.carReg}}</td>
<td>{{booking.parkingNumber}}</td>
<td>{{booking.date}}</td>
<td>
<div *ngIf="booking.cancelled" class="red">Cancelled</div>
<div *ngIf="!booking.cancelled" class="green">Booked</div>
</td>
<td>
<button class="btn btn-danger mr-2" (click)="cancelBooking(i)">Cancel</button>
</td>
</tr>
Table-viewer.component.html
<table class="table table-striped table-bordered table-hover">
...
<td>
<button class="btn btn-danger mr-2" (click)="cancelBooking(booking: Booking)">Cancel</button>
</td>
</tr>
table-viewer.component.ts
export class TableViewerComponent implements OnInit {
...
cancelBooking(booking): void {
booking.cancelled = !booking.cancelled
// or booking.cancelled = false; or whatever you want to do
}
}
Now, you have the change in the bookings array.
Next, you should implement a service to rewrite a json file.
https://stackoverflow.com/a/52242184/11218448

ngx-pagination is not getting updated after filtering data

I am using custom filters and ngx-pagination on my JSON data. The problem here is when I am filtering the data my pagination control is not getting updated, still showing the old page size and allowing pagination even if the data is not available. Please suggest.
Right now, it has 21 results without any filter applied
Now, I have applied filters n now it's showing only 1 record but pagination is still showing 5 pages (considering 5 per page size).
table-filter.pipe.ts
import { Pipe, PipeTransform } from "#angular/core";
#Pipe({
name: "tableFilter"
})
export class TableFilterPipe implements PipeTransform {
transform(list: any[], filters: any) {
const keys = Object.keys(filters).filter(key => filters[key]);
const filterUser = (user: { [x: string]: any; }) =>
keys.every(key => {
if (key == "sdob") {
return new Date(user["dob"]) >= new Date(filters[key]);
} else if (key == "edob") {
return new Date(filters[key]) >= new Date(user["dob"]);
} else {
return user[key] === filters[key];
}
});
return keys.length ? list.filter(filterUser) : list;
}
}
app.component.html
<table class="table table-sm table-responsive">
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Gender</th>
<th>DOB (mm/dd/yyyy)</th>
<th>Impact</th>
<th>Score</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser | tableFilter: form.value | paginate: { id: 'listing_pagination', itemsPerPage: 5, currentPage: page, totalItems: totalRecords }">
<td><input *ngIf="!isEdit" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()"></td>
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
<td>{{user.email}}</td>
<td>{{user.gender}}</td>
<td>{{user.dob}}</td>
<td>{{user.impact}}</td>
<td>
<div [ngClass]="getClass(user)">{{user.score}}</div>
</td>
<td>
<button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)">Edit</button>
<button class="btn btn-primary btn-sm btn-sm ml-2" (click)="deleteUser(user)">Delete</button>
</td>
</tr>
</tbody>
</table>
<pagination-controls id="listing_pagination" directionLinks="true" (pageChange)="page = $event"></pagination-controls>

How to retrieve dynamic box values (true or false if checked or not) - Angular 6

I use Angular 6, I get data from a JSON file and I display it in a table. I would like to be able to check the checkboxes in order to be able to carry out POST processing later for checkbox checked (so true).
The problem is that I get dynamic values so I have to be able to retrieve the value of a checkbox (true or false) even if the JSON file changes (adding data).
I can not get the value of checkbox (true or false) dynamically...
Can you help me please.
demande-ouverture-compte.component.html :
<h2>Demandes d'ouverture de compte</h2>
<hr>
<form #form = "ngForm" (ngSubmit) = "getVerificationCheckboxValidation(form)" [formGroup]="profileForm">
<table class="table table-striped table-dark">
<thead>
<tr>
<th scope="col">Nom</th>
<th scope="col">N° demande</th>
<th scope="col">date</th>
<th scope="col">Validation</th>
</tr>
</thead>
<tbody *ngFor="let demande of demandes; let i = index">
<tr>
<th scope="row">{{ demande.nom }}</th>
<td>{{ demande.id_demande }}</td>
<td>{{ demande.date }}</td>
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="test" id="customCheck{{ i }}" [checked]="demande.checked">
<label class="custom-control-label" for="customCheck{{ i }}">Valider la demande d'ouverture</label>
</div>
</td>
</tr>
</tbody>
</table>
<table>
<tr *ngFor="let demande of demandes; let j = index">
<td>
<input type="checkbox" [checked]="demande.checked" formControlName="hello" id="{{demande.roleID}}" />
</td>
<td>
</td>
<td>Voici demandes{{ j }}</td>
</tr>
</table>
<button class="col-2 offset-10 addAccount">Valider</button>
</form>
<!-- Remplacer le bouton valider par cette image -->
<!--<img src="../../assets/img/addAccount.svg" alt="" class="col-4 offset-7 addAccount">-->
demande-ouverture-compte.component.ts :
import { Component, OnInit } from '#angular/core';
import { DemandeOuvertureCompteService } from '../demande-ouverture-compte.service';
import { FormGroup, FormControl, NgForm } from '#angular/forms';
#Component({
selector: 'app-demande-ouverture-de-compte',
templateUrl: './demande-ouverture-de-compte.component.html',
styleUrls: ['./demande-ouverture-de-compte.component.scss']
})
export class DemandeOuvertureDeCompteComponent implements OnInit {
demandes: Object;
profileForm = new FormGroup({
hello: new FormControl('')
});
playerName: string;
constructor(private demandeOuvertureCompte: DemandeOuvertureCompteService) { }
ngOnInit() {
this.demandeOuvertureCompte.getDemandesOuvertureCompte().subscribe(
demandeOuvertureCompte => this.demandes = demandeOuvertureCompte
);
}
getVerificationCheckboxValidation(form: NgForm) {
console.log(form.value.test);
console.log(this.profileForm.value);
console.log("test");
console.log(this.playerName);
return this.playerName;
}
}
You can look for the valueChanges on FormGroup. Something like
ngOnInit() {
this.profileForm.valueChanges.subscribe(
value => console.log(value);
)