I am fetching datas from server but before the call gets completed the function gets called returning an empty array.I am new to RxJs could any one help me on it
getRows: (params) => {
setTimeout(() => {
const dataAfterSortingAndFiltering = this.sortAndFilter(audits.docs, params.sortModel, params.filterModel);
const rowsThisPage = dataAfterSortingAndFiltering.slice(0, audits.items.end);
let lastRow = -1;
if (dataAfterSortingAndFiltering.length <= params.endRow) {
lastRow = dataAfterSortingAndFiltering.length;
}
params.successCallback(rowsThisPage, lastRow);
}, 3000);
sortAndFilter function:
sortAndFilter(allOfTheData, sortModel, filterModel) {
return this.sortData(sortModel, this.filterData(filterModel, allOfTheData));
}
filterData function:
filterData(filterModel, data) {
const filterKeys = Object.keys(filterModel);
const filterPresent = filterModel && Object.keys(filterModel).length > 0;
if (!filterPresent) {
return data;
}
const resultOfFilter = [];
const filterParams = [];
for (let i = 0; i < filterKeys.length; i++) {
filterParams.push(`${filterKeys[i]}=${filterModel[filterKeys[i]].filter}`);
}
const params = filterParams.join('&');
this.auditService.getColumnSearch(params).pipe(first()).subscribe((datas: any) => {
resultOfFilter.push(...datas.docs);
});
return resultOfFilter;
}
SortData function:
sortData(sortModel, data) {
console.log('sortModel got called', sortModel);
console.log('data', data);
const sortPresent = sortModel && sortModel.length > 0;
if (!sortPresent) {
return data;
}
const resultOfSort = data.slice();
resultOfSort.sort((a, b) => {
for (let k = 0; k < sortModel.length; k++) {
const sortColModel = sortModel[k];
const valueA = a[sortColModel.colId];
const valueB = b[sortColModel.colId];
if (valueA == valueB) {
continue;
}
const sortDirection = sortColModel.sort === 'asc' ? 1 : -1;
if (valueA > valueB) {
return sortDirection;
} else {
return sortDirection * -1;
}
}
return 0;
});
return resultOfSort;
}
Before the server call gets completed the sortData function returns the data as [].
Leverage the feature of async and await
export class AuditComp {
getRows(params) {
setTimeout(() => {
const dataAfterSortingAndFiltering = this.sortAndFilter(audits.docs, params.sortModel, params.filterModel);
const rowsThisPage = dataAfterSortingAndFiltering.slice(0, audits.items.end);
let lastRow = -1;
if (dataAfterSortingAndFiltering.length <= params.endRow) {
lastRow = dataAfterSortingAndFiltering.length;
}
params.successCallback(rowsThisPage, lastRow);
}, 3000);
}
sortAndFilter(allOfTheData, sortModel, filterModel) {
return this.sortData(sortModel, this.filterData(filterModel, allOfTheData));
}
sortData(sortModel, data) {
console.log('sortModel got called', sortModel);
console.log('data', data);
const sortPresent = sortModel && sortModel.length > 0;
if (!sortPresent) {
return data;
}
const resultOfSort = data.slice();
resultOfSort.sort((a, b) => {
for (let k = 0; k < sortModel.length; k++) {
const sortColModel = sortModel[k];
const valueA = a[sortColModel.colId];
const valueB = b[sortColModel.colId];
if (valueA == valueB) {
continue;
}
const sortDirection = sortColModel.sort === 'asc' ? 1 : -1;
if (valueA > valueB) {
return sortDirection;
} else {
return sortDirection * -1;
}
}
return 0;
});
return resultOfSort;
}
async filterData(filterModel, data) {
const filterKeys = Object.keys(filterModel);
const filterPresent = filterModel && Object.keys(filterModel).length > 0;
if (!filterPresent) {
return data;
}
const resultOfFilter = [];
const filterParams = [];
for (let i = 0; i < filterKeys.length; i++) {
filterParams.push(`${filterKeys[i]}=${filterModel[filterKeys[i]].filter}`);
}
const params = filterParams.join('&');
await this.auditService.getColumnSearch(params).pipe(first()).toPromise()
.then((datas: any) => {
resultOfFilter.push(...datas.docs);
});
return resultOfFilter;
}
}
comment if faced any issue.
Related
I'm scraping a website using Playwright. but i have a problem. every time I do a page evaluate it always returns undefined data. but when I do console log in the evaluate page, the data appears on the console page, but doesn't appear in the terminal/command line
const table= await page.$eval("#txnHistoryList > tbody", (table) => {
let arrayData = [];
if (table != null) {
const rows = Array.from(table.querySelectorAll("tr"));
rows.forEach((row, rowIndex) => {
if (rowIndex > 1) {
const td = row.querySelectorAll("td");
let arrays = {};
if (td.length > 2) {
td.forEach((item, tdIndex) => {
if (tdIndex == 1) {
const date = item.innerText;
arrays.date = date ? date.toString().trim() : "";
}
if (tdIndex == 2) {
const transaction = item.innerText;
arrays.transaction = transaction
? transaction.toString().trim()
: "";
}
if (tdIndex == 4) {
const type = item.innerText;
arrays.type = type ? type.toString().trim() : "";
}
if (tdIndex == 5) {
const paymentAmount = item.innerText;
arrays.payment_amount = paymentAmount
? paymentAmount.toString().trim()
: "";
}
if (tdIndex == 6) {
const balance = item.innerText;
arrays.balance = balance ? balance.toString().trim() : "";
}
});
arrayData.push(arrays);
}
}
});
}
console.log(arrayData);
return arrayData;
});
console.log(tableMutasi);
const data = {
data: tableMutasi,
};
res.send(data);
Please help me
It's more safety to use locator in playwright. You can try something like that.
const someFunc = async () => {
const table = await page.locator('#txnHistoryList > tbody')
const arrayData = []
const isVisibleTable = await table.isVisible()
if (isVisibleTable) {
const rows = table.locator('tr')
const rowsCount = await rows.count()
for (let i = 0; i < rowsCount; i += 1) {
const row = rows.nth(i)
const tdLocator = row.locator('td')
const tdLocatorCount = await tdLocator.count()
const arrays = {}
if (tdLocatorCount > 2) {
for (let j = 0; j < tdLocatorCount; j += 1) {
switch (j) {
case 1: {
const date = await tdLocator.nth(j).innerText()
arrays.date = date ? date.toString().trim() : ''
break
}
case 2: {
const transaction = await tdLocator.nth(j).innerText()
arrays.transaction = transaction ? transaction.toString().trim() : ''
break
}
case 4: {
const type = await tdLocator.nth(j).innerText()
arrays.type = type ? type.toString().trim() : ''
break
}
case 5: {
const paymentAmount = tdLocator.nth(j).innerText()
arrays.payment_amount = paymentAmount ? paymentAmount.toString().trim() : ''
break
}
case 6: {
const balance = tdLocator.nth(j).innerText()
arrays.balance = balance ? balance.toString().trim() : ''
break
}
default:
continue
}
arrayData.push(arrays)
}
}
}
}
return arrayData
}
Docs: https://playwright.dev/docs/api/class-locator
I am trying to use callback function with forEach method to print in the console the result of 3 prompts but instead I have 5 outputs.
const personalMovieDB = {
genres: [],
writeYourGenres: function () {
for (let i = 1; i <= 3; i++) {
let favoriteGenre = [];
while (favoriteGenre == null || favoriteGenre == "") {
favoriteGenre = prompt(`Your favorite movie genre under number ${i}`);
this.genres[i - 1] = favoriteGenre;
}
this.genres.forEach((item, i) => {
console.log(`Favorite genre ${i+1} - ${item}`);
});
}
}
}
Just remove printing functionality from a loop
const personalMovieDB = {
genres: [],
writeYourGenres: function() {
for (let i = 1; i <= 3; i++) {
let favoriteGenre = [];
while (favoriteGenre == null || favoriteGenre == "") {
favoriteGenre = prompt(`Your favorite movie genre under number ${i}`);
this.genres[i - 1] = favoriteGenre;
}
}
this.genres.forEach((item, i) => {
console.log(`Favorite genre ${i+1} - ${item}`);
});
}
}
personalMovieDB.writeYourGenres()
const app = (() => {
let race1 = document.querySelector('.race1');
let race2 = document.querySelector('.race2');
let race3 = document.querySelector('.race3');
let race4 = document.querySelector('.race4');
let race5 = document.querySelector('.race5');
let race6 = document.querySelector('.race6');
const returnAll = () => {
fetch('php/index.php')
.then((response) => {
return response.json();
})
.then((myJson) => {
for (var i = 0; i < myJson.length; i++) {
if (myJson[i].race1 == 1) {race1.innerHTML += `<div>${myJson[i].email} </div>`}
if (myJson[i].race2 == 1) {race2.innerHTML += `<div>${myJson[i].email} </div>`}
if (myJson[i].race3 == 1) {race3.innerHTML += `<div>${myJson[i].email} </div>`}
if (myJson[i].race4 == 1) {race4.innerHTML += `<div>${myJson[i].email} </div>`}
if (myJson[i].race5 == 1) {race5.innerHTML += `<div>${myJson[i].email} </div>`}
if (myJson[i].race6 == 1) {race6.innerHTML += `<div>${myJson[i].email} </div>`}
}
});
console.log(allEnteries)
}
return {
init: () => {
returnAll();
}
}
})();
app.init();
All the information above is correct and works occordingly. I just need a better way to code this rather than multiple if statements, Switch would pretty mucch be the same!
Any suggestions? I find multple If statements are easy to read, however I've been told this is bad coding
Put them on an array:
let races =[];
races.push(document.querySelector('.race1'));
races.push(document.querySelector('.race2'));
...
races.push(document.querySelector('.race6'));
...
for (var i = 0; i < myJson.length; i++) {
if (myJson[i].races[i] == 1) {races[i].innerHTML += `<div>${myJson[i].email} </div>`}
Define the number of races as a variable, and use it to generate the dynamic variable variables you need:
const app = (() => {
let numRaces = 6,
raceElements = [ ];
for( var i = 0; i < numRaces; i++ )
{
raceElements.push( document.querySelector('.race'+(i+1)) );
}
const returnAll = () => {
fetch('php/index.php').then((response) => { return response.json(); }).then((myJson) => {
for (var i = 0; i < myJson.length; i++) {
for( var r = 0; r < numRaces; r++ )
{
if( myJson[i]['race'+(r + 1)])
{
raceElements[r].innerHTML+= '<div>'+myJson[i].email+'</div>';
}
}
}
});
console.log(allEnteries);
}
return {
init: () => {
returnAll();
}
}
})();
app.init();
With functionnal programming:
const races = Array(6).fill().map((_, k) => document.querySelector(`.race${k + 1}`));
const returnAll = () => {
fetch('php/index.php')
.then(response => response.json())
.then(json => races.forEach((race, i) => {
if (json[i][`race${i+1}`] === 1) {
race.innerHTML += `<div>${json[i].email} </div>`;
}
}));
};
I would to return a value, but I can not..
I do not know how I could do
The value that receives:
public filterOptions: Observable<string[]>;
My code that I would to return:
this.filterOptions = this.myForm.get('search').valueChanges.pipe(
startWith(null),
map((val) => {
if (!val) {
this.suscriptionSearch.unsubscribe();
return null;
}
if (this.bool) {
const filterValue = val.trim().toLowerCase();
const obj = {search: ''}
obj.search = filterValue;
this.suscriptionSearch = this.userService.searchUser(obj).subscribe((data)=>{
let monTab:string[] = [];
for (let index = 0; index < data.length; index++) {
monTab[index] = data[index].nom
}
return monTab.filter((option) => {
return option.toLowerCase().startsWith(filterValue)
}) //the value to return
});
}
}));
I found the solution .. I share it with you.
this.filterOptions = this.myForm.get('search').valueChanges.pipe(
startWith(null),
switchMap((val) => {
if (this.bool) {
const filterValue = val.trim().toLowerCase();
const obj = {search: ''}
obj.search = filterValue;
return this.userService.searchUser(obj).pipe(map((data)=>{
let monTab:string[] = [];
for (let index = 0; index < data.length; index++) {
monTab[index] = data[index].nom
}
console.log(monTab);
return monTab.filter((option) => {
return option.toLowerCase().startsWith(filterValue)
});
}))
} else {
return of(null);
}
}));
In javascript I have a method which has a function inside of it, when trying to document It with the program JSdocs I assumed that It would have to look like this:
/**
* #memberof dataBase#query
* #inner
* #function makeArray
* #description ..
*/
or like this:
/**
* #function dataBase#query~makeArray
* #description ..
*/
But for some reason it does not show up.
Question: Is there any way for me to document this kind of function?
EDIT:
You may notice some places in my code below where on line continues on to the next line, this is simply because of the limited space provided by the stackoverflow question box and is not part of my source code.
Here is the code I want to document (specifically the makeArray function inside of the query method):
exports.dataBase = class dataBase {
constructor(connection, X64) {
this.connectString = connection
this.X64 = X64
this.connection = adodb.open(connection, X64)
this._this = this
this.shortcuts = require('./shortcuts')
}
async close() {
await this.connection.close()
return
}
async reopen() {
this.connection = adodb.open(this.connectString, this.X64)
return
}
async shortcut(type, data) {
await this.shortcuts.data[type](data, this._this)
return
}
async runSQL(sql) {
let type
if(sql.match('SELECT')) {
type = 'query'
} else {
type = 'execute'
}
let data
let self = this
await new Promise((resolve, reject) => {
self.connection[type](sql).then(result => {
data = result
resolve()
}).catch(err => {
console.log(err)
})
}).catch(err => {
console.log(err)
})
return data
}
async query(table, columns = '*' || [], rows = '*' || [], options = '*'
|| []) {
function makeArray(str) {
if(typeof str === 'string' && str !== '*') {
return [str]
}
}
makeArray(columns)
makeArray(rows)
makeArray(options)
function processData(table, columns, rows, options) {
function processColumns(columns) {
let retval = ''
for(let i in columns) {
if(i != columns.length - 1) {
retval += `${columns[i]},`
} else {
retval += `${columns[i]}`
return retval
}
}
}
function processRows(rows) {
let retval = ''
for(let i in rows) {
if(i != rows.length - 1) {
retval += `ID=${rows[i]} AND `
} else {
retval += `ID=${rows[i]}`
}
}
return retval
}
function processOptions(options) {
let retval = ''
for(let i in rows) {
retval += ` AND ${options[i]}`
}
return retval
}
let SQLcolumns = processColumns(columns)
let SQLrows = processRows(rows)
let SQLoptions = processOptions(options)
if(rows === '*' && options === '*') {
return `SELECT ${SQLcolumns} FROM [${table}];`
} else if(options === '*') {
return `SELECT ${SQLcolumns} FROM [${table}] WHERE ${SQLrows};`
} else if(rows === '*') {
return `SELECT ${SQLcolumns} FROM [${table}] WHERE ${SQLoptions};`
} else {
return `SELECT ${SQLcolumns} FROM [${table}] WHERE
${SQLrows}${SQLoptions};`
}
}
let data
await this.runSQL(processData(table, columns, rows,
options)).then((result) => {
data = result
}).catch(err => {
console.log(err)
})
return data
}
async createTable(name, columns, rows = null) {
function processColumns(columns) {
let retval = ''
for(let i of Object.keys(columns)) {
if(i !== Object.keys(columns)[columns.size() - 1]) {
retval += `${i} ${columns[i]},\n`
} else {
retval += `${i} ${columns[i]}`
}
}
return retval
}
let data
let SQLcolumns = processColumns(columns)
await this.runSQL(`CREATE TABLE ${name}
(\n${SQLcolumns}\n);`).then((result) => {
data = result
})
if(rows !== null) {
this.addRecords(name, rows)
}
}
async addRecords(table, values) {
let data = []
function processValues(values) {
let retval = ''
for(let i of Object.keys(values)) {
if(i !== Object.keys(values)[values.size() - 1]) {
retval += `${values[i]}, `
} else {
retval += values[i]
}
}
return retval
}
for(let i of values) {
let SQLvalues
SQLvalues = processValues(i)
await this.runSQL(`INSERT INTO [${table}] VALUES
(${SQLvalues});`).then((result) => {
data.push(result)
})
}
return data
}
}