How to show data to angular? - html

list.component.ts
import { Component, OnInit } from '#angular/core';
import { StudentAPIService } from 'src/app/services/student-api.service';
import { Student } from 'src/app/model/student';
#Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
constructor( private studentAPI: StudentAPIService ) { }
ngOnInit(): void {
this.studentAPI.studentList().subscribe(res=>{
console.log(res);
return res;
});
}
}
list.component.html
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="center">
<table id="student_Table">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of res">
<td>{{ row.student_name }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
I am new in angular and I want to show data in list.component.html table. In ts file I have successfully fetch data through an API and data are showing in console.log(res) but unable to show in table. So, How can I do this? Please help me.
Thank You

You have to define the variable (and it should be public) in the class definition, then assign the service response to that variable. So;
#Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
constructor( private studentAPI: StudentAPIService ) { }
public res: any | any[]; // you can create an interface to the data type
ngOnInit(): void {
this.studentAPI.studentList().subscribe(res=>{
this.res = res;
});
}
}

You can use async pipe and get rid of subscribing inside component. Because async pipe will auto unsubscribe when component destroyed.
export class ListComponent implements OnInit {
response$:Observable<IStudentList[]>;
constructor( private studentAPI: StudentAPIService ) { }
ngOnInit(): void {
this.response$ = this.studentAPI.studentList();
}
}
Now You can iterate response$ like below..
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="center">
<table id="student_Table">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of response$ | async">
<td>{{ row.student_name }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
See above <tr *ngFor="let row of response$ | async"> this is auto-subscribe and you will get your list data in html and iterate over it and display it.

Related

adding ngb-pagination will not load the page

The documentation on ngb-pagination in https://ng-bootstrap.github.io/#/components/pagination/overview causes the page to not load after adding this
<ngb-pagination
[(page)]="page"
[pageSize]="pageSize"
[collectionSize]="items.length"></ngb-pagination>
Here is my HTML file
<div class="body d-flex ">
<table class="table table-hover ">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | slice: (page-1) * pageSize : page * pageSize">
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>{{user.email}}</td>
<td>action</td>
</tr>
</tbody>
</table>
<ngb-pagination [(page)]="page" [pageSize]="pageSize" [collectionSize]="users.length"></ngb-pagination>
</div>
Here is the ts file
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { environment } from 'src/environments/environment';
#Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.scss'],
})
export class TableComponent implements OnInit {
readonly API_PATH = '/user/all';
users: any[] = [];
page = 1;
pageSize = 5;
constructor(private api: HttpClient) {}
async ngOnInit() {
this.displayAllUsers();
}
private async displayAllUsers() {
var users: any = await this.getUsers();
this.getResult(users);
}
private async getUsers(): Promise<any> {
return await this.api.get(environment.API_URL + this.API_PATH).toPromise();
}
private getResult(result: any) {
if (result.success) {
this.users = this.toArray(result.data);
} else {
console.log(result.data);
}
}
private toArray(result: any): any[] {
var list = [];
for (var items in result) {
list.push(result[items]);
}
return list;
}
}
if I remove ngb-pagination snippet the page seems to load perfectly fine, but adding the snippet will fail to load the page
Add the #angular/localize package to your packages.json:
npm install #angular/localize --save
Add this to your polyfills.ts:
import '#angular/localize/init';
This worked for me, when I was having the same problem after upgrading from Angular 6 to 12 and ng-bootstrap 10.

i have user adding form, each user has delete button. how can i make it delete it's user?

user.model.ts // interface for user
export interface User {
id:number,
firstName:string,
lastName:string,
eMail:string
}
form.component.ts
import { Component, OnInit } from '#angular/core';
import { User } from '../interfaces/user.model';
#Component({
***
})
export class FormComponent implements OnInit {
idNumber: number = 0;
userInfo: User[] = [];
constructor() { }
addUser(firstname: HTMLInputElement, lastname: HTMLInputElement, email: HTMLInputElement) {
this.idNumber += 1;
this.userInfo.push({ id: this.idNumber, firstName: firstname.value, lastName: lastname.value, eMail: email.value });
console.log(this.userInfo)
***
}
ngOnInit(): void {
}
}
table.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
***
})
export class TableComponent implements OnInit {
#Input() users:any;
constructor() { }
ngOnInit(): void {
}
}
table.component.html
there is a delete button for each user I add. I want them to delete users which belong to them. is it possible to pass the user index?
<table class="ui celled table">
<thead>
***
</thead>
<tbody>
<tr *ngFor="let user of users">
<td>{{user.id}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.eMail}}</td>
<td style="width: 40px;" ><button class="delButton"><i class="times icon"></i></button></td>
</tr>
</tbody>
</table>
Try following code
<table class="ui celled table">
<thead>
***
</thead>
<tbody>
<tr *ngFor="let user of users;let i = index">
<td>{{user.id}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.eMail}}</td>
<td style="width: 40px;" ><button class="delButton" (click)="deleteUser(i)"><i class="times icon"></i></button></td>
</tr>
</tbody>
And inside the table.component.ts file add the following function
deleteUser(index: number) { this.users.splice(index, 1); }

How to hide the full row if any cell value is null in angular

I would like to hide the row for the while payment due date cell is empty for the respective row.
while any value of Payment Due Date is null or empty I would like to hide the whole row respectively.
user.service.ts
import { Injectable } from '#angular/core';
import { HttpClient} from '#angular/common/http'
#Injectable({
providedIn: 'root'
})
export class UsersService {
constructor( private http:HttpClient) { }
getData(){
let url="https://Test.azurewebsites.net/api/accounts/getall";
return this.http.get(url);
}
}
app.component.ts
import { analyzeAndValidateNgModules } from '#angular/compiler';
import { Component } from '#angular/core';
import { UsersService} from './users.service'
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'coding-test';
data : any
constructor( private user:UsersService){
this.user.getData().subscribe(data=>{
console.warn(data)
this.data = data
})
}
}
app.component.html
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-6">Display Sorted Account Info</h1>
<table class="table table-striped" >
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th >Amount Due</th>
<th>Payment Due Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of data" >
<td>{{item.LastName}},{{item.FirstName}}</td>
<td>{{item.Email}}</td>
<td>{{item.PhoneNumber | phone}}</td>
<td>{{item.AmountDue | currency}}</td>
<td>{{item.PaymentDueDate | date}}</td>
</tr>
</tbody>
</table>
</div>
</div>
on app.component.ts you can add filter by changing ((this.data = data )) to :
this.data = data.filter(x=>x.PaymentDueDate !== null );
Try to filter out the object based on the condition in your ts file.This will solve your problem.

How to bind Json response to table

I have products.components.ts class, where I am getting Json data in this.Getdata
ngOnInit() {
this._service.getProducts(this.baseUrl)
.subscribe(data => {
this.Getdata=data
this.products=data
alert(JSON.stringify(this.Getdata));
});
This Josn data I want to bind in products.components.html class Table
<p>
Product List
</p>
<table>
<th>Id</th> <th>Name</th> <th> Country</th> <th>Actions</th>
<tr *ngFor="let lst of products; let i = index" border="1">
<td>{{i+1}}</td><td>{{lst.id}}</td><td>{{lst.employee_name}}</td> <td>Edit</td>
</tr>
</table>
The above code is not working. Only alert displaying. How can I bind data to table?
This is my Json data
[{"id":"1","employee_name":"amit","employee_salary":"0","employee_age":"0","profile_image":""},{"id":"247793","employee_name":"Ana","employee_salary":"123","employee_age":"123","profile_image":""},{"id":"247856","employee_name":"Joseph Beltran","employee_salary":"1000","employee_age":"23","profile_image":""},{"id":"247982","employee_name":"testyeyyeye1","employee_salary":"123","employee_age":"23","profile_image":""},{"id":"248007","employee_name":"test100","employee_salary":"123","employee_age":"23","profile_image":""},{"id":"248038","employee_name":"Hendry","employee_salary":"61888","employee_age":"26","profile_image":""}]
Model class
export class Productlist {
id: string;
employee_name: string;
employee_salary: string;
employee_age: string;
profile_image: string;
}
Instead of subscribing to the Observable, consider storing it in a property and then unwrapping it in the template using the async pipe.
If you consider that, then you can significantly reduce your Component to this:
import { Component } from '#angular/core';
import { Observable } from 'rxjs';
import { EmployeeService } from './employee.service';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
employees$: Observable<Array<any>> = this.employeeService.getEmployees();
constructor(private employeeService: EmployeeService) {}
}
And in your Template:
<p>
Employee List
</p>
<table border="1">
<thead>
<th>Id</th>
<th>Name</th>
<th> Country</th>
<th>Actions</th>
</thead>
<tbody>
<tr *ngFor="let employee of employees$ | async; let i = index">
<td>{{i+1}}</td>
<td>{{employee.id}}</td>
<td>{{employee.employee_name}}</td>
<td>Edit</td>
</tr>
</tbody>
</table>
Here's a Working Sample Demo Code for your ref.
PS: Consider naming your properties and methods appropriately. If you're working with employees, then it doesn't really make sense to name properties and methods as products.
You can also use
const myobject= JSON.parse(yourjsonvalue);
You will get the object in myobject and now you can loop through with simple ngFor.
I got it this way
export class ProductsComponent implements OnInit {
public Getdata;
products:Productlist[];
constructor(private employeeService: ProductService) {}
ngOnInit() {
this.employeeService.getProducts(this.baseUrl)
.subscribe((data:any) => {
this.products=data;
});
}
}

I'm getting Cannot read property 'appendChild' of null(on chrome) and this.container is null(on firefox) errors when I started using material dialog

I have a table in my frontend that has a list of all my users from a MySQL database using a spring API. I wanted to create a material dialog that would open when clicking on a user but for some reason I'm getting a bunch of errors on firefox and chrome which are mentioned above and I haven't found anything online to help even though I followed many tutorials to create the angular dialog but i still got the same erros.
Here's my component html that has the list of users:
<div class="container-scroller">
<app-navbar></app-navbar>
<div class="container-fluid page-body-wrapper">
<app-sidebar></app-sidebar>
<div class="main-panel">
<div class="content-wrapper">
<div class="row">
<div class="col-lg-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title" style="font-weight: 600">Users List</h4>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Id</th>
<th>Profile Picture</th>
<th>Username</th>
<th>Last Name</th>
<th>First Name</th>
<th>Email</th>
<th>Enabled</th>
<th>Registered Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let u of users" (click)="openDialog()" id="myId">
<td>{{u.id}}</td>
<td>{{u.profilePicture}}</td>
<td>{{u.username}}</td>
<td>{{u.lastName}}</td>
<td>{{u.firstName}}</td>
<td>{{u.email}}</td>
<ng-container *ngIf="u.enabled; else elseTemplate">
<td class="text-success">{{u.enabled}}</td>
</ng-container>
<ng-template #elseTemplate>
<td class="text-danger">{{u.enabled}}</td>
</ng-template>
<td>{{ u.registeredDate | date: shortDate }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
the .ts file:
import { Component, OnInit } from '#angular/core';
import { ViewEncapsulation } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { UserService } from '../user.service';
import { MatDialog, MatDialogConfig } from '#angular/material';
import { NewDialogComponent } from '../new-dialog/new-dialog.component';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['../app.component.scss', './dashboard.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class DashboardComponent implements OnInit {
loginuser: any = {};
users: any[] = [];
constructor(private service: UserService, private dialog: MatDialog) {
this.loginuser = JSON.parse(localStorage.getItem('currentUser'));
this.service.getAllUsers(this.loginuser.token).subscribe(u => {
this.users = u;
console.log(this.users);
});
}
ngOnInit() {
}
openDialog() {
console.log('selected item: ', selectedItem);
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = {
id: 1,
title: 'Angular for Beginners'
};
this.dialog.open(NewDialogComponent, dialogConfig);
const dialogRef = this.dialog.open(NewDialogComponent, dialogConfig);
}
}
and here's the new dialog html component:
<h2 mat-dialog-title>This is a Dialog title</h2>
<mat-dialog-content>
<p> Place content here </p>
</mat-dialog-content>
<mat-dialog-actions>
<button class="mat-raised-button" (click)="close()">Close</button>
</mat-dialog-actions>
and the .ts file:
import { Component, OnInit, Inject } from '#angular/core';
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '#angular/material';
#Component({
selector: 'app-new-dialog',
templateUrl: './new-dialog.component.html',
styleUrls: ['./new-dialog.component.scss']
})
export class NewDialogComponent implements OnInit {
description: string;
constructor(private fb: FormBuilder, private dialogRef: MatDialogRef<NewDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any) {
this.description = data.description;
}
ngOnInit() {}
close() {
this.dialogRef.close();
}
}
At first glance, it looks like you're opening your dialog twice:
this.dialog.open(NewDialogComponent, dialogConfig);
const dialogRef = this.dialog.open(NewDialogComponent, dialogConfig);
Not sure if that is what is causing the exact error, but it's the first thing I noticed.
Update:
It looks now to me like this line is the error:
this.description = data.description;
I'm not seeing any property being set for "description"-- just 'id' and 'title'.