Kendo UI for Angular authenticationModel - kendo-ui-angular2

I am new in programming and I am trying to connect a Progress database using Progress Developer Studio authentication model (/WEB-INF/oeablSecurity-form-local.xml) with KENDO UI for Angular project. When I am using anonymous authentication everything is working fine, but I couldn't manage to make Form authentication with username and password. This is the code:
/// <reference path="progress/progress.d.ts" />
import { Component, ViewChild, Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Observable, BehaviorSubject } from 'rxjs/Rx';
import {
GridComponent,
GridDataResult,
DataStateChangeEvent,
// State
} from '#progress/kendo-angular-grid';
import {
State,
process
} from '#progress/kendo-data-query';
import * as Progress from "./progress/progress";
let progress = Progress.progress;
/* Example service */
#Injectable()
export class CategoriesService extends BehaviorSubject<GridDataResult> {
private tableName: string = 'Client';
private jsdoPromise: Promise<Progress.progress.data.JSDO>;
constructor(private http: Http) {
super(null);
const serviceURI = 'serviceURI';
const catalogURI = 'catalogURI';
let opts: Progress.progress.data.JSDOSessionOptions = {
serviceURI: serviceURI,
};
let session = new progress.data.JSDOSession(opts);
this.jsdoPromise = new Promise( (resolve, reject) => {
session.login("", "").done(function (session: Progress.progress.data.JSDOSession, result: any, info: any) {
console.log("session.login");
session.addCatalog(catalogURI).then(() => {
resolve(new progress.data.JSDO('AdvClients'));
});
})
})
}
public query(state: any): void {
this.fetch(this.tableName, state)
.subscribe(x => super.next(x));
}
private fetch(tableName: string, state: State): Observable<GridDataResult> {
let that = this;
let query = {
skip: state.skip,
top: state.take
};
let promise = new Promise((resolve, reject) => {
this.jsdoPromise.then((jsdo) => {
console.log("jsdoPromise.resolve");
let afterFill = (jsdo: any, success: any, request: any) => {
jsdo.unsubscribe('AfterFill', afterFill, this);
if (success) {
let data = jsdo.getData();
if (query.top) {
let afterInvoke = (jsdo1: any, success1: any, request1: any): void => {
jsdo.unsubscribe('AfterInvoke', 'count', afterInvoke, this);
console.log("promise.resolve 1");
resolve(<GridDataResult>{
data: data,
total: request1.response.numRecs
});
};
jsdo.subscribe('AfterInvoke', 'count', afterInvoke, this);
jsdo.count(query);
} else {
console.log("promise.resolve 2");
resolve(<GridDataResult>{
data: data,
total: data.length
});
}
} else {
reject(new Error('Error while executing query'));
}
};
jsdo.subscribe('AfterFill', afterFill, this);
jsdo.fill(query);
})
});
let result = Observable.fromPromise(promise)
.map((ret: GridDataResult) => (<GridDataResult>{
data: ret.data,
total: ret.total
}));
return result;
}
}

I made it.
const serviceURI = 'http://ctc-server:8810/CtcIdea';
const catalogURI = serviceURI + '/static/CtcIdeaService1.json';
const authenticationModel = progress.data.Session.AUTH_TYPE_FORM;
let opts: Progress.progress.data.JSDOSessionOptions = {
serviceURI: serviceURI,
authenticationModel: authenticationModel
};

Related

Issue with testing middleware in a nodejs express typescript project

I have been following https://github.com/goldbergyoni/nodebestpractices to learn more about nodejs best practices.
I have the following middleware that I implemented:
import { NextFunction, Request, Response } from "express";
import { BAD_REQUEST_ERROR_TYPES } from "../constants";
import { BadRequestError } from "./../error-handling";
const isAccountActive = (req: Request, res: Response, next: NextFunction) => {
if (req.session?.user?.isEmailVerified) {
next();
} else {
next(new BadRequestError(BAD_REQUEST_ERROR_TYPES.ACCOUNT_NOT_ACTIVE));
}
};
export default isAccountActive;
This is the test that I wrote for it:
describe("isAccountActive Middleware", () => {
describe("Recieving a request", () => {
test("When the request has a userUUID set in the session, it calls the next function without throwing a Bad Request Account Not Active error", async () => {
// Arrange
const req = {
method: "GET",
url: "/user/42",
session: {
user: {
userUUID: "some-string",
},
},
} as unknown as Request;
const res = jest.fn as unknown as Response;
const next = jest.fn;
// Act
await isAccountActive(req, res, next);
// Assert
expect(next).toBeCalledTimes(1);
expect(next).toBeCalledWith(
new BadRequestError(BAD_REQUEST_ERROR_TYPES.ACCOUNT_NOT_ACTIVE)
);
});
});
});
That is implementation number 3 for that test. I also tried using sinon, and node-mocks-http.
When I run the test command, I get the following error regardless of any implementation:
My app builds and runs fine; so I am not quite sure why jest would be throwing this error when the actuall server code itself is being compiled and run without any issues.
For reference, my config.ts:
import { isFullRedisURL } from "./helpers";
import { z } from "zod";
import { REDIS_URL_ERROR } from "./constants";
import { StartupError } from "./error-handling";
const input = {
environment: process.env.NODE_ENV,
basePort: process.env.BASE_PORT,
redisUrl: process.env.REDIS_URL,
redisPassword: process.env.REDIS_PASSWORD,
databaseUrl: process.env.DATABASE_URL,
sessionSecret: process.env.SESSION_SECRET,
};
const configSchema = z.object({
environment: z.string(),
basePort: z.coerce.number().positive().int(),
redisUrl: z
.string()
.refine((val) => isFullRedisURL(val), { message: REDIS_URL_ERROR }),
redisPassword: z.string(),
databaseUrl: z.string(),
sessionSecret: z.string().min(8),
});
let parsedInput;
try {
parsedInput = configSchema.parse(input);
} catch (e) {
throw new StartupError("Config validation error", e);
}
export const config = parsedInput;
export type Config = z.infer<typeof configSchema>;
my error-handling/error-handling-middleware.ts
import { COMMON_ERRORS, STATUS_CODES } from "../constants";
import { NextFunction, Request, Response } from "express";
import errorHandler from "./errorHandler";
import { config } from "../config";
const errorHandlingMiddleware = async (
// eslint-disable-next-line #typescript-eslint/no-explicit-any
error: any,
req: Request,
res: Response,
next: NextFunction
) => {
if (error && typeof error === "object") {
if (error.isTrusted === undefined || error.isTrusted === null) {
error.isTrusted = true; // Error during a specific request is usually not fatal and should not lead to process exit
}
}
errorHandler.handleError(error);
const { environment } = config;
const result = {
status: error?.httpStatus || STATUS_CODES.InternalServerError,
name: error?.name || COMMON_ERRORS.InternalServerError,
message: error?.message || "Sorry, something went wrong.",
details: error?.details,
stacktrace: environment === "development" ? error?.stacktrace : undefined,
};
res
.status(error?.httpStatus || STATUS_CODES.InternalServerError)
.send(result);
};
export default errorHandlingMiddleware;
the StartupError class:
import { FieldError } from "__shared/types";
import {
COMMON_ERRORS,
BAD_REQUEST_ERROR_MESSAGES,
BAD_REQUEST_ERROR_TYPES,
STATUS_CODES,
} from "../constants";
export class ApplicationError extends Error {
constructor(
public name: string,
public message: string,
public httpStatus: STATUS_CODES = STATUS_CODES.InternalServerError,
public isTrusted: boolean = true,
public isOperational: boolean = true,
public details?: FieldError[],
public stacktrace?: unknown
) {
super(message); // 'Error' breaks prototype chain here
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
this.name = name;
this.httpStatus = httpStatus;
this.isOperational = isOperational;
this.isTrusted = isTrusted;
this.details = details;
this.stacktrace = stacktrace;
Error.captureStackTrace(this, this.constructor);
}
}
export class BadRequestError extends ApplicationError {
constructor(type: keyof typeof BAD_REQUEST_ERROR_TYPES) {
super(
COMMON_ERRORS.BadRequestError,
BAD_REQUEST_ERROR_MESSAGES[type],
STATUS_CODES.BadRequest,
true,
true
);
}
}
export class StartupError extends ApplicationError {
constructor(reason: string, error: unknown) {
super(
COMMON_ERRORS.StartupError,
`Start up failed: (${reason}) `,
STATUS_CODES.InternalServerError,
false,
true,
undefined,
error
);
}
}

I am trying to host a project I built on two separate repositories

I have a MEAN stack project that is built on two separate repositories. The backend is using Node.js and handles all API routing to MongoDB Atlas. If i wanted to host this on something like firebase, how would I go about that? I am not sure of any way to do this and haven't found similar scenarios such as this online.
This is an example of one of the components from the frontend.
The html file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FamilyService } from '../family.service';
import { IncomeService } from '../income.service';
#Component({
selector: 'app-income',
templateUrl: './income.component.html',
styleUrls: ['./income.component.scss']
})
export class IncomeComponent implements OnInit {
date: any;
family: any;
amount: any;
Incomes: any = [];
Families: any = [];
constructor(private router: Router, private familyService: FamilyService, private incomeService: IncomeService) {
this.date = new Date().toDateString();
this.family = ""
this.amount = ""
}
ngOnInit(): void {
this.getFamilies()
this.getIncomes()
}
createNewIncome(){
let request = {
family: this.family,
amount: this.amount,
Date: this.date
}
console.log(request.family);
this.incomeService.createIncome(request).subscribe((response: any) => {
this.getIncomes()
});
}
getFamilies(){
let familyInfo:any = []
this.familyService.getFamily().subscribe((res: any) => {
let arr = res
arr.forEach((family: any) => {
// console.log(element)
if(family.status == "active"){
familyInfo.push(family)
}
});
});
console.log(familyInfo);
this.Families = familyInfo
}
getIncomes(){
let incomeInfo:any = []
this.incomeService.getIncome().subscribe((res: any) => {
let arr = res
arr.forEach((element: any) => {
// console.log(element)
incomeInfo.push(element)
});
});
console.log(incomeInfo);
this.Incomes = incomeInfo
}
goToPage(PageName:string):void{
this.router.navigate([`${PageName}`]);
// else
// outterrormessage
}
addEntry():void{
console.log(this.date + " " + this.family + " " + this.amount)
let entry = {
Date: this.date,
family: this.family,
amount: this.amount
}
this.Incomes.push(entry)
console.log(this.Incomes)
}
deleteEntry(entry:any):void {
if(confirm("Are you sure you would like to delete this entry?")){
this.incomeService.deleteIncome(entry._id).subscribe((res: any) => {
this.getIncomes() // Once the record gets deleted we refetch
})
}
}
updateEntry(entry:any):void {
if(confirm("Are you sure you would like to update this entry?")){
this.incomeService.updateIncome(entry._id, entry).subscribe((res:any) => {
this.getIncomes() // After the record gets edited we refetch
})
}
}
toggleEditEntry(entry:any){
entry.isEditing = !entry.isEditing;
}
}
The service.ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FamilyService } from '../family.service';
import { IncomeService } from '../income.service';
#Component({
selector: 'app-income',
templateUrl: './income.component.html',
styleUrls: ['./income.component.scss']
})
export class IncomeComponent implements OnInit {
date: any;
family: any;
amount: any;
Incomes: any = [];
Families: any = [];
constructor(private router: Router, private familyService: FamilyService, private incomeService: IncomeService) {
this.date = new Date().toDateString();
this.family = ""
this.amount = ""
}
ngOnInit(): void {
this.getFamilies()
this.getIncomes()
}
createNewIncome(){
let request = {
family: this.family,
amount: this.amount,
Date: this.date
}
console.log(request.family);
this.incomeService.createIncome(request).subscribe((response: any) => {
this.getIncomes()
});
}
getFamilies(){
let familyInfo:any = []
this.familyService.getFamily().subscribe((res: any) => {
let arr = res
arr.forEach((family: any) => {
// console.log(element)
if(family.status == "active"){
familyInfo.push(family)
}
});
});
console.log(familyInfo);
this.Families = familyInfo
}
getIncomes(){
let incomeInfo:any = []
this.incomeService.getIncome().subscribe((res: any) => {
let arr = res
arr.forEach((element: any) => {
// console.log(element)
incomeInfo.push(element)
});
});
console.log(incomeInfo);
this.Incomes = incomeInfo
}
goToPage(PageName:string):void{
this.router.navigate([`${PageName}`]);
// else
// outterrormessage
}
addEntry():void{
console.log(this.date + " " + this.family + " " + this.amount)
let entry = {
Date: this.date,
family: this.family,
amount: this.amount
}
this.Incomes.push(entry)
console.log(this.Incomes)
}
deleteEntry(entry:any):void {
if(confirm("Are you sure you would like to delete this entry?")){
this.incomeService.deleteIncome(entry._id).subscribe((res: any) => {
this.getIncomes() // Once the record gets deleted we refetch
})
}
}
updateEntry(entry:any):void {
if(confirm("Are you sure you would like to update this entry?")){
this.incomeService.updateIncome(entry._id, entry).subscribe((res:any) => {
this.getIncomes() // After the record gets edited we refetch
})
}
}
toggleEditEntry(entry:any){
entry.isEditing = !entry.isEditing;
}
}
The web service
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class WebRequestService {
//Root URL wrapped in constant
readonly ROOT_URL;
//Returns http method observables
constructor(private http: HttpClient) {
this.ROOT_URL = `http://localhost:3000`;
}
//Getting one
get(uri: string) {
return this.http.get(`${this.ROOT_URL}/${uri}`);
}
//Creating one
post(uri: string, payload: Object) {
return this.http.post(`${this.ROOT_URL}/${uri}`, payload);
}
//Updating one
patch(uri: string, payload: Object) {
return this.http.patch(`${this.ROOT_URL}/${uri}`, payload);
}
//Deleting one
delete(uri: string) {
return this.http.delete(`${this.ROOT_URL}/${uri}`);
}
}
This is my first time working with Angular and a MEAN stack so I apologize for the poor programming practices here.If you need I can also upload the backend code: routes, models, and service files.

How can I cover Axios-retry failure unit testing using Mocha chai Nodejs?

How can we unit test the following code (axios-retry logic)
AxiosRetryClass.ts
import { AxiosInstance, AxiosRequestConfig } from 'axios';
import axiosRetry from 'axios-retry';
export class AxiosRetryClass {
constructor() {
}
public async callAxios(axiosConfig: AxiosRequestConfig): Promise<any> {
const instance = new AxiosSession().getAxiosInstance();
axiosRetry(instance, {
retries: 3,
retryCondition: (error: any) => {
return error.response.status === 500;
},
retryDelay: (count: number, err: any) => {
return 1 * 60 * 1000;
},
});
let response = { status: 0};
try {
response = await instance(axiosConfig);
} catch (error: any) {
response = error;
console.log(`AxiosClass: call error ${error}`);
}
return response;
}
}
AxiosSession.ts
import {HttpsCookieAgent, HttpCookieAgent } from 'http-cookie-agent';
import { CookieJar } from 'tough-cookie';
import axios from 'axios';
export class AxiosSession {
constructor() {}
public getAxiosInstance(): Promise<any> {
const agents = {
httpAgent: new HttpCookieAgent({ new CookieJar(), true }),
httpsAgent: new HttpsCookieAgent({ new CookieJar(), true }),
}
const instance = axios.create(agents);
return instance;
}
}
AxiosRetry.spec.ts
import Axios, { AxiosInstance } from 'axios';
import chai from 'chai';
import sinon, { SinonStub } from 'sinon';
import chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
describe(‘AxiosClassTest ', () => {
let sinonStub: sinon.SinonSandbox;
beforeEach(() => {
sinonStub = sinon.createSandbox();
});
it(‘Test Axios retry’, async () => {
let instance = {} as AxiosInstance;
instance.get = sinonStub.stub().rejects({status: 500}); //Tried both returns and rejects
const session = new AxiosSession();
session.getAxiosInstance = sinonStub.stub().returns(instance);
const axiosClass = new AxiosClass();
const url = `dummy-error-url`
await axiosClass.callAxios({ url, method: ‘GET’ });
});
});
Note: Test case is running successfully. But axios-retry code not covered. I mean the below code
axiosRetry(instance, {
retries: 3,
retryCondition: (error: any) => {
return error.response.status === 500;
},
retryDelay: (count: number, err: any) => {
return 1 * 60 * 1000;
},
});

List is not updated for existing clients in socketIO

I am working on chat application, using socketIO
Whenever user signed in sucessfully, user is navigated to dashboard and list of current loggedin users will be displayed.
Whenever new user is signed in, existing user list is not getting updated.
Adding the necessary code here
events: backend
let verifyClaim = require("./tokenLib");
let socketio = require("socket.io");
let tokenLibs = require('./tokenLib');
let setService = (server) => {
let onlineUsers = [];
let io = socketio.listen(server);
let myio = io.of('')
myio.on('connection', (socket) => {
console.log(' emitting verify user');
socket.emit("verifyUser", "");
socket.on('set-user', (authToken) => {
console.log(authToken);
tokenLibs.verifyTokenWithoutSecret(authToken, (user, err,) => {
if (user) {
console.log(user);
let currentUser = user;
socket.userId = currentUser._id;
let fullName = `${currentUser.name}`
console.log(`${fullName} is online`);
socket.emit(currentUser._id, `${fullName} is online`)
let userObj = { userId: currentUser._id, name: fullName }
onlineUsers.push(userObj);
console.log(onlineUsers)
socket.emit('userlist', onlineUsers)
}
else {
socket.emit('auth-error', { status: 500, error: 'Please provide valid token ' })
}
})
})
socket.on('disconnect', () => {
console.log('user is disconnected');
let removeUserId = onlineUsers.map(function (user) { return user.userId }).indexOf(socket.userId)
onlineUsers.splice(removeUserId, 1)
console.log(onlineUsers)
})
})
}
module.exports = { setService: setService }
socket service:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class SocketService {
public prod = 'https://todolistbe.herokuapp.com/api/v1';
public dev = 'http://localhost:3001';
public baseUrl = this.dev;
private socket;
constructor(public http: HttpClient) {
this.socket=io('http://localhost:3001')
}
public verifyUser=()=>{
return Observable.create((observer)=>{
this.socket.on('verifyUser',(data)=>{
observer.next(data);
})
})
}
public setUser=(authToken)=>{
this.socket.emit("set-user",authToken)
}
public userList=()=>{
return Observable.create((observer)=>{
this.socket.on('userlist',(data)=>{
observer.next(data);
})
})
}
public welcomeUser=(userid)=>{
return Observable.create((observer)=>{
this.socket.on(userid,(data)=>{
observer.next(data);
})
})
}
public disconnectUser = () => {
return Observable.create((observer) => {
this.socket.on('disconnect', () => {
observer.next()
})
})
}
}
dashboard:
import { Component, OnInit } from '#angular/core';
import { ThemePalette } from '#angular/material/core';
import { SocketService } from '../../socket.service';
import { ToastrService } from 'ngx-toastr';
export interface Task {
name: string;
completed: boolean;
color: ThemePalette;
subtasks?: Task[];
}
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css'],
providers: [SocketService]
})
export class DashboardComponent implements OnInit {
public authToken: any = localStorage.getItem('authToken');
public userList: any = [];
public userNotification;
allComplete: boolean = false;
ngOnInit(): void {
this.verifyUserConfirmation();
this.getOnlineUsers();
}
public verifyUserConfirmation: any = () => {
this.SocketService.verifyUser().subscribe((data) => {
console.log(this.authToken)
this.SocketService.setUser(this.authToken);
this.getOnlineUsers();
})
}
selected = 'option2';
toggleNavbar() {
console.log('toggled' + this.isMenuOpened);
this.isMenuOpened = !this.isMenuOpened;
}
getOnlineUsers() {
// this.SocketService.welcomeUser(localStorage.getItem('id')).subscribe((data)=>{
// this.userNotification=data;
// console.log("hi:"+this.userNotification)
// })
this.SocketService.userList().subscribe((user) => {
this.userList = [];
for (let x in user) {
let tmp = { 'user': x, 'name': user[x] }
this.userList.push(tmp);
}
console.log(this.userList)
})
}
}
Whenever you want to emit an event with all other users, we should use myio.emit instead of socket.io.
Issue is resolved when i made necessary changed in my backend events library

Get Large Set of Data (~20000 item) from mongodb and display it in angular 7 Admin Products Page

I'm trying to get ~20000 items from Mongodb and display them at my Angular 7 Project in Admin Products Page in a table
The Problem is that the website takes too much time and sometimes it crashes
Is there a way to get them as 1000 item after another, get them fastly, or paginate them as 0-1000 item in a page 1 and 1000-2000 in page 2?
I searched for it and I didn't find any useful resource or even a similar question here.
I found that I could limit number of get items in mongodb through this code:
ITEMS_COLLECTION.find({}).limit(1000).toArray((err, allItems) => {
items = allItems
})
I don't want to just limit it to 1000, I want get all of them and display them without crashing the browser or not to be so slow.
This is the Item Page: src > Item.js
function getItems() {
let items
Server().then((server_data) => {
server_data.ITEMS_COLLECTION.find({}).limit(1000).toArray((err, allItems) => {
items = allItems
})
})
/*eslint no-undef: 0*/
return new Promise(resolve => {
setTimeout(() => {
resolve(items)
}, 4000)
})
}
This is the server page: src > server.js
app.get('/activeProducts', (req, res) => {
Item.getActiveItems()
.then(active_items => {
res.send(active_items);
})
.catch(err => {
throw new CustomError('Could not get Active Items', err);
});
});
This is the Products Service:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { LoginService } from './login.service';
import { Router } from '#angular/router';
import { MatDialog, MatDialogRef } from '#angular/material';
import { environment } from '../../environments/environment';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'my-auth-token'
})
};
#Injectable()
export class ProductsService {
products = this.http.get(
` ${environment.link_url_with_backend}/activeProducts`
);
cached_products;
constructor(
private loginService: LoginService,
private router: Router,
private http: HttpClient,
public dialogRef: MatDialog
) {
this.products.subscribe(data => {
console.log(data);
this.cached_products = data;
});
}
}
This is the Products Component:
export class ProductsComponent implements OnInit, DoCheck {
constructor(private productService: ProductsService) {}
products;
ngOnInit() {
this.products = this.productService.cached_products;
}
}
This is the Products HTML:
<div
class="products-container wrapper"
>
<app-product
*ngFor="let product of products"
[product]="product"
style="width: 360px;"
></app-product>
</div>
First of All In The Backend you need to get the first 100 for example:
function getFirst100Items() {
let items
ITEMS_COLLECTION
.find({})
.limit(100)
.sort({id: 1})
.toArray( (err, allItems) => {
items = allItems
})
return new Promise(resolve => {
setTimeout(() => {
resolve(items)
}, 2000)
})
}
Then you can add load more function for example:
function getMore100Items(loadedItems) {
let items
server_data.ITEMS_COLLECTION
.find({ id: { $gte: loadedItems } })
.limit(100)
.sort({id: 1})
.toArray( (err, allItems) => {
items = allItems
})
return new Promise(resolve => {
setTimeout(() => {
resolve(items)
}, 2000)
})
}
function getItemsCount() {
let itemsCounts
server_data.ITEMS_COLLECTION.countDocuments()
.then( (counts) => {
itemsCounts = counts
})
return new Promise(resolve => {
setTimeout(() => {
resolve({itemsCounts})
}, 1000)
})
}
Then You Specify the express routes
app.get('/first/100products', (req, res) => {
Item.getFirst100Items()
.then(items => {
res.send(items);
})
.catch(err => {
throw new CustomError('Could not get Items', err);
});
});
app.post('/loadmore/products', (req, res) => {
loaded_items = req.body.loadedItems
res.send({loaded_items})
});
app.get('/loadmore/products', (req, res) => {
setTimeout(() => {
Item.getMore100Items(loaded_items)
.then(items => {
res.send(items);
})
.catch(err => {
throw new CustomError('Could not get Items', err);
});
}, 2000);
});
Second In Angular 7
Parent Component
loadedItems = 0;
#ViewChild(AdminTableComponent) adminTable;
constructor(public dialog: MatDialog, private http: HttpClient) {
this.http
.get(` ${environment.link_url_with_backend}/first/100products`)
.subscribe((data: {}[]) => {
this.products_data = data;
this.dataSource = new MatTableDataSource(this.products_data);
});
}
ngOnInit() {}
loadMore() {
this.http
.get(` ${environment.link_url_with_backend}/products/length`)
.subscribe((itemsCount: any) => {
if (this.loadedItems < itemsCount.itemsCounts - 100) {
this.adminTable.isLoad = true;
this.loadedItems += 100;
this.http
.post(
`${environment.link_url_with_backend}/loadmore/products`,
JSON.stringify({ loadedItems: this.loadedItems }),
httpOptions
)
.subscribe(data => {
console.log(data);
});
this.http
.get(` ${environment.link_url_with_backend}/loadmore/products`)
.subscribe((items: {}[]) => {
items.map(product => {
this.products_data.push(product);
this.dataSource = new MatTableDataSource(this.products_data);
this.adminTable.isLoad = false;
this.adminTable.dataSource.sort = this.adminTable.sort;
this.adminTable.dataSource.paginator = this.adminTable.paginator;
return;
});
});
} else {
this.adminTable.isLoad = false;
this.adminTable.isLoadMore = false;
alert('No More Products to Get');
return;
}
});
}
ChildComponent
loadMoreItems() {
this.loadMore.emit('loadMore');
}
#Input() dataSource;
#Input() displayedColumns;
#Input() dialogComponent;
#Output() loadMore = new EventEmitter();
isLoad = false;
isLoadMore = false;
And you can continue from here
Hope this helps!
Note: All this is just an example so don't take it exactly

Resources