react-table version 7 onSortedChange callback equivalent - react-table

I'm trying to migrate to react-table version 7 https://www.npmjs.com/package/react-table. My existing code has a callback for onSortedChange but I can't figure out how to replicate this with the new version 7 hooks.
Version 6 format:
<ReactTable
onSortedChange={myCallbackFn}
/>
Version 7:
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable(
{
columns,
data,
defaultColumn,
filterTypes
},
useFilters,
useSortBy
);
...
Appreciate any suggestions!

I spent a couple hours trying to do this, then figured it out 2 minutes after posting my question.
const { state: { sortBy }} = useTable(...)
React.useEffect(() => {
// `sortBy` changed
}, [sortBy])

Sorry for jumping in but I'm curious if you got this to work fully. I have the same issue as you except for filtering and following your solution I still don't get it to work.
I do:
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
sortBy,
filterBy,
} = useTable({
columns,
data,
defaultColumn,
filterTypes,
},
useFilters,
useSortBy
)
React.useEffect(() => {
console.log('sort by changed: '+sortBy);
}, [sortBy])
React.useEffect(() => {
console.log('filter by changed');
}, [filterBy])
And I get both logs at initial load/render of my table but nothing more, no logs when I sort or filter my table. Did you do anything more which you didn't post?

Related

RTK query `use*Query` is using cached isLoading and data even for different args

I'm new to RTK query and I'm having issues with it sharing data across queries with different args.
// api.js
const { useGetStuffQuery } = api.injectEndpoints({
endpoints: (builder) => ({
getStuff: builder.query({
query: (stuffId) => ({ url: `http://some.random-url.com/${stuffId}` }),
}),
}),
});
// component.js
function(props) {
const [id, setId] = useState(1);
const { data, isLoading } = useGetStuffQuery(id);
if (val === '2') {
console.log('datttt', data); // this initially prints data from id:1
}
return <div>
<input value={id} onChange={(e) => setId(e.target.value)} />
{
isLoading ? <span>loading...</span>
: <span>data is: {data}</span>
}
</div>
}
I was expecting to see the loading indicator to show up once I changed the id from 1 to 2.
However, it seems like rtkQuery is still using the cached data from my previous useGetStuffQuery(1) call and hence I see the data for id1 momentarily. Once the request for id2 is resolved -- it does update and rerender my component.
Is this caching behavior intentional and expected? Or am I missing something?
It is intentional, there are isLoading and isFetching that are behaving different (isLoading until there is data, isFetching while any request is running) and for convenience the hook will always give you the last data that was known so your UI jumps less.
This is explained in the "Query Loading State" docs section:
isLoading refers to a query being in flight for the first time for the given endpoint + query param combination. No data will be available at this time.
isFetching refers to a query being in flight for the given endpoint + query param combination, but not necessarily for the first time. Data may be available from an earlier request at this time.

wordpress-woocommerce rest api is so slow

I'm trying to create 100k products in woocommerce through woocommerce rest api.
But it takes too long to get response from woocommerce. It takes almost 3 minutes per 100 data.
It's normal situation? or Is there any way to solve this issue?
help me please. Thank you in advance.
const CreateToWP = function (data) {
let data_batch = {
create: []
};
data_batch['create'].push(data)
return WooCommerce.post("products/batch", data_batch)
.then((res) => {
console.log(res.data.create.length)
})

Metascraper Consolidated Data

I'm using metascraper in a project I'm working on. I'm passing in custom rules into the contructor. It's actually scraping actual content from the page its scraping. The problem is, is that it appears to be finding every tag that matches the CSS selector, and combining all of the text() content from every tag on the page. I checked metascraper website and github and couldn't find any information about an option that changes this kind of mode/behavior. I made sure that each scrape request creates a new instance of metascraper in case it was just using the same member variables across multiple uses of the object, but that didn't seem to do anything. Any thoughts?
Edit: Also, ideally, metascraper would return an array of arrays of sets of selectors it finds. I have 4 selectors in a group that appear in groups throughout a page. I need it to iterate over the selectors in order, until it cannot find any more instances of the 1st selector (aka the groups have stopped appearing on the page).
type4: async (page: Page): Promise<Extract[]> => {
const html = await page.content()
const url = await page.url()
const type4MetascraperInstance = createType4MetaScraperInstance()
const metadata = await type4MetascraperInstance({ html: html, url: url })
console.log('metadata: ', metadata)
const extract: Extract[] = [{
fingerprint: 'type4',
author: metadata.author,
body: metadata.description,
images: null,
logo: null,
product: null,
rating: null,
title: metadata.title,
videos: null
}]
return extract
}
The function for creating the Type4 metascraper instance is:
function createType4MetaScraperInstance() {
const toDescription = toRule(description)
const toAuthor = toRule(author)
const toTitle = toRule(title, { removeSeparator: false })
const type4MetaScraperInstance = metaScraper([ {
author: [
toAuthor($ => $('.a-profile-name').text()),
],
title: [
toTitle($ => $('a[data-hook="review-title"] > span').text()),
],
description: [
toDescription($ => $('.review-text-content').text()),
]
} ])
return type4MetaScraperInstance
}
I decided to architect a different solution here that uses a python script to properly parse reviews, and it will need to read/write to google cloud datastore. Some suggestions people provided were to write my own calls to cheeriojs (https://cheerio.js.org/), instead of using metascraper at all.

Wrong output on Sqlite query in ionic 3

I'm building an ionic app with a SQlite database.
I can already put data in the database, but when I run a simple query to get data, I get really weird feedback.
My simple code
this.databaseService.execQuery('SELECT * FROM timelog WHERE id = ? ORDER BY id DESC',[this.ongoingTimelog.id])
.then((data) => {
console.log(data);
debugger;
});
execQuery(query: string, params?: Array<string | number>): Promise<any> {
return new Promise((resolve, reject) => {
if (!query) {
resolve();
}
this.db.executeSql(query, params)
.then((result: any) => {
resolve(result);
})
});
}
So normally I would suspect (as I get on my pc envoirement) the data to be like data.rows[0].id...
But on my tablet I get the following:
data on phone
Does anybody have any idea why i get something completely different and how I can get the correct data?
Thanks in advance!!
What you see is the javascript wrapper of the SQLite. That wrapper make possible to talk with js and be common for Android and iOS.
Your data is there, the screenshot shows you have one item. To access you need:
this.databaseService.execQuery('SELECT * FROM timelog WHERE id = ? ORDER BY id DESC',[this.ongoingTimelog.id])
.then((data) => {
console.log(data.rows.item(0));
debugger;
});
Needs data.rows.item(0).id instead of data.rows[0].id
Check this sample app it could help. cordova-sqlite-storage-starter-app

Get count result with knex.js / bookshelf.js

I'm trying to perform a simple count with knex (since it seems to not be supported by bookshelf yet). The following code is working:
bookshelf.knex('hosts').count('id').then(function(total) {
res.send({
meta: {
total: total[0]['count(`id`)']
}
});
});
It just seems odd to me that I have to do total[0]['count('id')'] to get the actual result. Am I doing things right here?
Thanks!
All the results from knex.js are arrays. A query could be successful and simply return 0 results.
Also, you can alias the column directly in the column name (or count() call). Like this:
bookshelf.knex('hosts').count('id as CNT').then(function(total) {
res.send({
meta: {
total: total[0].CNT
}
});
});
Still need to get the first element, but you can reference the column as a normal JSON property.
While knex does return results as arrays, it also has a method for returning the first result, which will be an object--not an array. It's pretty simple to get straight to the count without having to rely on [0] or anything to access your count within an array. For your example, a cleaner solution could be:
bookshelf
.knex("hosts")
.count("id")
.first()
.then(function(total) {
res.send({
meta: {
total: total.count
}
});
});
code for node js
let result = await knex.count("id").from('events').first();
if (result) {
console.log(result.count);
}
this seems to work correctly and is a bit simpler
knex('Quotes').count('quoteBody')
.then((res)=>{
//console.log("rows "+JSON.stringify(res))
console.log("rowspl2 "+res[0]['count(`quoteBody`)'])
})
.catch((err)=>{
console.log("err "+err)
})
or try it like this
knex('Quotes').count('quoteBody', {as: 'rows'})
.then((res)=>{
// console.log("rows "+JSON.stringify(res))
console.log("rowsp "+res[0]['rows'])
})
.catch((err)=>{
console.log("err "+err)
})

Resources