adding ngb-pagination will not load the page - html

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.

Related

I'm trying to do a http get request to get data from my backend Larval, MYSQL I have created the API in Laravel but cant display the data in Angular

I'm new to programming and new advise please here is my code
employees component
import { DataService } from './../../service/data.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-employees',
templateUrl: './employees.component.html',
styleUrls: ['./employees.component.css'
]})
export class EmployeesComponent implements OnInit {
employees: any
constructor(private dataservice: DataService) { }
ngOnInit() {
}
getEmployeesData() {
this.dataservice.getData().subscribe((res: any) => {
this.employees = res;
});
}
}
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
getData: any;
constructor(private httpClient: HttpClient) {
this.httpClient.get('http://127.0.0.1:8000/api/employees')
};
}
HTML
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Surname</th>
<th scope="col">Email</th>
<th scope="col">Salary</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let emp of employees">
<th scope="row">{{emp.id}}</th>
<td>{{emp.name}}</td>
<td>{{emp.surname}}</td>
<td>{{emp.email}}</td>
<td>{{emp.salary}}</td>
</tr>
</tbody>
I see a couple of things, that cause the Data not to show up.
data.service.ts:
Your fetching the Data in the Constructor but you do ignore the return Value of your call. I suggest you do the call in a separate function that will be called if the data is needed.
constructor(private httpClient: HttpClient) {}
loadAllEmployees(): Observable<any> {
return this.httpClient.get('http://127.0.0.1:8000/api/employees');
}
Employees Component:
It seems, that you do not call the getEmployeesData function. Therefore your employees never get any Data.
employees: any
constructor(private dataservice: DataService) { }
ngOnInit() {
this.getEmployeesData();
}
getEmployeesData() {
this.dataservice.loadAllEmployees().subscribe((res: any) => {
this.employees = res;
});
}
With this setup, your data should load and be displayed.
Besides that, I would suggest you define the Type of the Employee and do not work with any. It does make it easier to read and understand your code. You are also less likely to get any Errors regarding types.

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); }

angular api datatable : no data found

I'm trying to make a table with this API:
https://run.mocky.io/v3/70e5b0ad-7112-41c5-853e-b382a39e65b7/people
the html structure of my table appears but not the data of my API and I have no error in the console
Do you have a solution ?
here is the structure of my rest component (code of my table):
people.ts
export class people {
id: string;
firstname: string;
lastname: string;
email: string;
mobile: string;
city: string;
country: string;
constructor(id,firstName,lastName,email,mobile,city,country){
this.id=id;
this.firstname=firstName;
this.lastname=lastName;
this.email=email;
this.mobile=mobile;
this.city=city;
this.country=country;
}
}
rest.component.html
<h1>Employee Dashboard</h1>
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Address</th>
<th>City</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr *ngFor= "let user of users">
<td>{{people.id}}</td>
<td>{{people.firstname}}</td>
<td>{{people.lastname}}</td>
<td>{{people.email}}</td>
<td>{{people.address}}</td>
<td>{{people.city}}</td>
<td>{{people.country}}</td>
</tr>
</tbody>
</table>
rest.component.spec.ts
import { TestBed, async } from '#angular/core/testing';
import { RouterTestingModule } from '#angular/router/testing';
import { AppComponent } from './rest.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'project'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('project');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to project!');
});
});
rest.component.ts
import { Component, OnInit } from '#angular/core';
import { people } from './people';
import { RestService } from './rest.service';
#Component({
selector: 'app-root',
templateUrl: './rest.component.html',
styleUrls: ['./rest.component.css']
})
export class RestComponent implements OnInit {
people: people[] = [];
constructor(public rs: RestService){
}
ngOnInit():void {
this.rs.getUsers().subscribe((response) => {
this.people=response;
})
}
title = 'project';
}
rest.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { people } from './people'
#Injectable({
providedIn: 'root'
})
export class RestService {
constructor(private http:HttpClient){}
url:string= "https://run.mocky.io/v3/70e5b0ad-7112-41c5-853e-b382a39e65b7/people";
getUsers(){
return this.http.get<people[]>(this.url);
}
}
The actual array of People objects is under a property named "people" in the API response. So, modify the service code:
getUsers(){
return this.http.get<any>(this.url).pipe(
map(response) => {
return response['people'];
})
);
}
The code you will need to change will be in two files
rest.component.html
Replace this
<tr *ngFor= "let user of users">
<td>{{people.id}}</td>
<td>{{people.firstname}}</td>
<td>{{people.lastname}}</td>
<td>{{people.email}}</td>
<td>{{people.address}}</td>
<td>{{people.city}}</td>
<td>{{people.country}}</td>
</tr>
with this
<tr *ngFor= "let user of users">
<td>{{user.id}}</td>
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td>{{user.address}}</td>
<td>{{user.city}}</td>
<td>{{user.country}}</td>
</tr>
In rest.component.ts
Replace
ngOnInit():void {
this.rs.getUsers().subscribe((response) => {
this.people=response;
})
with this
ngOnInit():void {
this.rs.getUsers().subscribe((response) => {
this.users=response.people;
})
It should be user.id not people.id
<tr *ngFor= "let user of users">
<td>{{user.id}}</td>
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td>{{user.address}}</td>
<td>{{user.city}}</td>
<td>{{user.country}}</td>
</tr>
The problem with code is you saving data in people and in frontend you are using user which is not defined.
<tbody>
<tr *ngFor= "let p of people">
<td>{{p.id}}</td>
<td>{{p.firstname}}</td>
<td>{{p.lastname}}</td>
<td>{{p.email}}</td>
<td>{{p.address}}</td>
<td>{{p.city}}</td>
<td>{{p.country}}</td>
</tr>
</tbody>

"formGroup expects a FormGroup instance. Please pass one in." Error when trying to display table

Trying to understand how to solve this problem. I was following a tutorial and I seem to be doing everything properly but still getting this error.
My web API is working properly when I tested in Postman. I also was getting a error involving CORS which I solved but this is the last error I need solved. Sorry if this is too basic of a question but I cant seem to be able to find a solution online that i can understand.
Here is my HTML and TS file
HTML
<div class="myContent">
<form [formGroup]="viewClientsForm" (ngSubmit)="getClients(viewClientsForm)">
<div style="text-align:center;padding-left:20px;padding-right:20px">
<br />
<br />
<div class="table-responsive">
<table class="table table-bordered">
<tr style="background-color:rgba(220,230,242,1); font-size:12pt">
<th style="text-align:left;">First Name</th>
<th style="text-align:left;">Last Name</th>
<th style="text-align:left;">Phone Number</th>
<th style="text-align:left;">Amount</th>
<th style="text-align:left;">Status</th>
</tr>
<tr *ngFor="let clients of client" style="background-color:white">
<td> {{clients.FirstName }} </td>
<td> {{clients.LastName }} </td>
<td> {{clients.HomeNumber}} </td>
<td> {{clients.AssetValue}} </td>
<td> {{clients.AccountStatus }} </td>
</tr>
</table>
</div>
</div>
</form>
</div>
TS file
import { Component, OnInit } from '#angular/core';
import { IClient } from '../CPM-Interfaces/client';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '#angular/forms';
import { ClientService } from '../services/clientService/client.service';
#Component({
selector: 'app-view-clients',
templateUrl: './view-clients.component.html',
styleUrls: ['./view-clients.component.css']
})
export class ViewClientsComponent implements OnInit {
viewClientsForm: FormGroup;
client: IClient[];
errorMsg: string = null;
showMsgDiv: boolean = false;
constructor(private formBuilder: FormBuilder, private clientService: ClientService) { }
ngOnInit() {
this.getClients();
if (this.client == null) {
this.showMsgDiv = true;
}
}
getClients() {
this.clientService.GetClients().subscribe(
responseProductData => {
this.client = responseProductData;
this.showMsgDiv = false;
},
responseProductError => {
this.client = null;
this.errorMsg = responseProductError;
console.log(this.errorMsg);
}
);
}
}
In the template,
You have bonded viewClientsForm variable to formGroup property.
<form [formGroup]="viewClientsForm" (ngSubmit)="getClients(viewClientsForm)">
viewClientsForm is defined but the value is null. That's why angular is throwing errors.
You either have to define a FormGroup instance or remove the binding if it's not used
like:
<form (ngSubmit)="getClients(viewClientsForm)">
It's because viewClientsForm value is null
import { Component, OnInit } from '#angular/core';
import { IClient } from '../CPM-Interfaces/client';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '#angular/forms';
import { ClientService } from '../services/clientService/client.service';
#Component({
selector: 'app-view-clients',
templateUrl: './view-clients.component.html',
styleUrls: ['./view-clients.component.css']
})
export class ViewClientsComponent implements OnInit {
// HERE you can do viewClientsForm = this.formBuilder.group({...etc})
viewClientsForm: FormGroup;
client: IClient[];
errorMsg: string = null;
showMsgDiv: boolean = false;
constructor(private formBuilder: FormBuilder, private clientService: ClientService) { }
ngOnInit() {
this.getClients();
if (this.client == null) {
this.showMsgDiv = true;
}
}
getClients() {
this.clientService.GetClients().subscribe(
responseProductData => {
this.client = responseProductData;
this.showMsgDiv = false;
},
responseProductError => {
this.client = null;
this.errorMsg = responseProductError;
console.log(this.errorMsg);
}
);
}
}

Difficulty fetching json data from API using Angular

I am trying to fetch data from API https://sportsbook.draftkings.com/api/odds/v1/leagues/3/offers/gamelines.json
and store them in table in my Angular Application. Initial 15 rows are displayed on my page, not all the rows. And I cannot fetch line data which is nested inside outcome object.
Here is my HTML code
<div class="row">
<mat-toolbar color="primary">
<span>Welcome!</span>
</mat-toolbar>
<div class="container">
<br>
<h2>Information</h2>
<span class="right">API endpoint</span>
<table class="table table-hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>HomeTeamName</th>
<th>AwayTeamName</th>
<th>Start Date</th>
<th>Offers</th>
<th>Line</th>
<!--<th>Image</th>-->
</tr>
</thead>
<tbody>
<ng-container *ngFor="let data of data.events">
<tr>
<td>{{data.id}}</td>
<td>{{data.name }}</td>
<td>{{data.homeTeamName }}</td>
<td>{{data.awayTeamName}}</td>
<td>{{data.startDate }}</td>
<td>{{data.offers[1].label }}</td>
<td>{{data.offers.outcomes[2].line }}
<!--<td><img class="image-width" src="{{contact.image}}" alt="{{contact.name}}}"></td>-->
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
Here is my typescript code
import { Component, OnInit } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs/add/operator/map';
import { MatTableDataSource, MatSort } from '#angular/material';
import { DataSource } from '#angular/cdk/table';
#Component({
selector: 'app-draftking',
templateUrl: './draftking.component.html',
styleUrls: ['./draftking.component.css']
})
export class DraftkingComponent implements OnInit {
private apiUrl = 'https://sportsbook.draftkings.com/api/odds/v1/leagues/3/offers/gamelines.json';
displayedColumns = ['id','name', 'homeTeamName','awayTeamName','offers','line'];
data: any = {};
dataSource = this.data;
constructor(private http: Http) {
this.getLeague1();
this.getData1();
}
getData1(){
return this.http.get(this.apiUrl)
.map((res: Response) => res.json())
}
getLeague1() {
this.getData1().subscribe(data => {
console.log(data);
this.data = data
})
}
ngOnInit() {
}
}
Typically you setup your actual server call in a service (called model because it models your data). Here is one of mine as an example.
service.ts
#Injectable()
export class ApiService {
constructor(private http: HttpClient) { }
public get<T>(path: string, routerParams?: Params): Observable<T> {
let queryParams: Params = {};
if (routerParams) {
queryParams = this.setParameter(routerParams);
}
return this.http.get<T>(this.path(path), { params: queryParams });
}
public put<T>(path: string, body: Object = {}): Observable<any> {
return this.http.put(this.path(path), body);
}
public post<T>(path: string, body: Object = {}): Observable<any> {
return this.http.post(this.path(path), body);
}
public delete<T>(path: string): Observable<any> {
return this.http.delete(this.path(path));
}
...
In my components (sometimes other services) I will call an API method and expect results in the form of an Observable. So in your case I'd use my service like this:
component
constructor(private apiService: ApiService) { }
ngOnInit() {
this.apiService('https://pathtoserver').subscribe(data => {
if (data.id) {
this.setCurrentUser();
}
});
}
Hey remember to NOT call getData1(); more than once or you'll have 2 "hot" subscriptions. Use .pipe(take(1)).sub... in order to end subscriptions once they give you something.