performance remote el-select option 3000 items slow and crush? - meteor

Hello this is my first time. I have problem with like that I have 3000 items and I use framework like vue, element-ui and meteor. I pull all the items through a remote el-select that selects to add more remote select array object.I don't know why it slow performance and crush.
This is my picture
// Find item opts method
_getItemOpts(query, type) {
type = type || 'remote'
let exp = new RegExp(query)
let selector = {}
if (exp) {
selector = {
itemType: { $ne: 'Bundle' },
// , 'Sale'
activityType: { $in: ['Purchase'] },
status: 'Active',
$or: [
{ name: { $regex: exp, $options: 'i' } },
{ refNo: { $regex: exp, $options: 'i' } },
{ barcode: { $regex: exp, $options: 'i' } },
],
}
}
// Find item
findItems
.callPromise({ selector: selector })
.then(result => {
// console.log(result)
if (type == 'remote') {
this.itemOpts = result
}
this.loading = false
})
.catch(err => {
this.loading = false
Notify.error({ message: err })
})
},
Please help me.

Well no magick is here. U tryin to add to DOM 3000 of elements, so no wonder its crashes. Try to narrow results, for example show them only when user enters 3 letters

Related

Gatsby-Source-Wordpress: Error when compiling. TypeError: Cannot destructure property 'fields' of 'nodesType' as it is undefined

When I go and try to run gatsby develop I get the following error:
TypeError: Cannot destructure property 'fields' of 'nodesType' as it is undefined.
at generateNodeQueriesFromIngestibleFields (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/steps/ingest-remote-schema/buil
d-queries-from-introspection/generate-queries-from-ingestable-types.js:155:13)
at buildNodeQueries (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/steps/ingest-remote-schema/build-queries-from-introspe
ction/build-node-queries.js:25:25)
at runSteps (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/utils/run-steps.ts:41:9)
at runSteps (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/utils/run-steps.ts:43:9)
at ingestRemoteSchema (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/steps/ingest-remote-schema/index.js:49:5)
at runSteps (/Users/repoFolder/Work/gatsby/node_modules/gatsby-source-wordpress/src/utils/run-steps.ts:41:9)
at runAPI (/Users/repoFolder/Work/gatsby/node_modules/gatsby/src/utils/api-runner-node.js:487:16)
ERROR #gatsby-source-wordpress_112003
gatsby-source-wordpress
Encountered a critical error when running the buildNodeQueries build step.
See above for more information.
not finished createSchemaCustomization - 3.831s
not finished [gatsby-source-wordpress] ingest WPGraphQL schema - 2.379s
I haven't made any changes, or upgraded packages and have since been working on other projects. I tried disabling the Related Posts plugin, as well as a few others in addition to upgrading the gatsby-source-wordpress plugin.
I am configuring the plugin like in my gatsby-config.js:
{
resolve: "gatsby-source-wordpress",
options: {
url: `${process.env.WPGRAPHQL_URL}`,
verbose: false,
develop: {
hardCacheData: false,
},
schema: {
perPage: 10, // currently set to 100
requestConcurrency: 3, // currently set to 15
previewRequestConcurrency: 1, // currently set to 5
},
type: {
Page: {
exclude: true,
},
Menu: {
exclude: true,
},
MenuItem: {
exclude: true,
},
},
debug: {
graphql: {
onlyReportCriticalErrors: true,
},
},
searchAndReplace: [
{
search: `${process.env.GATSBY_WORDPRESS_URL_PROTOCOL}://${process.env.GATSBY_WORDPRESS_URL_PATH}`,
replace: `${process.env.GATSBY_SITE_URL_PROTOCOL}://${process.env.GATSBY_SITE_URL_PATH}`,
},
],
html: {
useGatsbyImage: true,
},
},
},
and I am configuring the plugin / constructing the node ingatsby-node.jslike the following:
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions
const BlogPostTemplate = path.resolve("./src/templates/BlogPost.tsx")
const BlogTagPostsTemplate = path.resolve(
"./src/templates/BlogTagPosts.tsx"
)
const BlogCategoryPostsTemplate = path.resolve(
"./src/templates/BlogCategoryPosts.tsx"
)
const BlogPostsResult = await graphql(`
{
allWpPost {
edges {
node {
id
slug
uri
link
title
excerpt
date(formatString: "MMMM DD, YYYY")
modified(formatString: "MMMM DD, YYYY")
author {
node {
avatar {
url
}
id
name
uri
slug
}
}
featuredImage {
node {
localFile {
childImageSharp {
gatsbyImageData(
width: 1920
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
)
}
}
}
}
categories {
nodes {
id
count
name
slug
}
}
tags {
nodes {
id
count
name
slug
}
}
}
}
}
}
`)
if (BlogPostsResult.errors) {
reporter.panicOnBuild("Error while running GraphQL query.")
return
}
const BlogPosts = BlogPostsResult.data.allWpPost.edges
BlogPosts.forEach((post, index) => {
const date = post.node.date
createPage({
path: `/${post.node.categories.nodes[0].slug}/${moment(date).format(
"YYYY"
)}/${moment(date).format("MM")}/${post.node.slug}.html`,
component: BlogPostTemplate,
context: {
id: post.node.id,
slug: post.node.slug,
uri: post.node.uri,
previous: index === 0 ? null : BlogPosts[index - 1].node,
next:
index === BlogPosts.length - 1
? null
: BlogPosts[index + 1].node,
},
})
})
createPaginatedPages({
edges: BlogPosts,
createPage: createPage,
pageTemplate: "src/templates/BlogPosts.tsx",
pageLength: 10,
pathPrefix: "blog",
})
const BlogTagPosts = new Map()
const BlogCategoryPosts = new Map()
BlogPosts.forEach((post) => {
const tags = post.node.tags.nodes
if (tags && tags.length > 0) {
tags.forEach((tag) => {
if (BlogTagPosts.has(tag.slug)) {
BlogTagPosts.set(tag.slug, [
...BlogTagPosts.get(tag.slug),
post,
])
} else {
BlogTagPosts.set(tag.slug, [post])
}
if (BlogTagPosts.has(tag.title)) {
BlogTagPosts.set(tag.title, [
...BlogTagPosts.get(tag.title),
post,
])
} else {
BlogTagPosts.set(tag.title, [post])
}
})
}
const categories = post.node.categories.nodes
if (categories && categories.length > 0) {
categories.forEach((category) => {
if (BlogCategoryPosts.has(category.slug)) {
BlogCategoryPosts.set(category.slug, [
...BlogCategoryPosts.get(category.slug),
post,
])
} else {
BlogCategoryPosts.set(category.slug, [post])
}
if (BlogCategoryPosts.has(category.title)) {
BlogCategoryPosts.set(category.title, [
...BlogCategoryPosts.get(category.title),
post,
])
} else {
BlogCategoryPosts.set(category.title, [post])
}
})
}
})
const BlogTagSlugs = [...BlogTagPosts.keys()]
const BlogCategorySlugs = [...BlogCategoryPosts.keys()]
//const BlogCategoryTitles = [...BlogCategoryPosts.keys()];
if (BlogTagSlugs.length > 0) {
BlogTagSlugs.forEach((BlogTagSlug) => {
createPage({
path: `/tag/${BlogTagSlug}`,
component: BlogTagPostsTemplate,
context: {
group: BlogTagPosts.get(BlogTagSlug),
slug: BlogTagSlug,
title: BlogTagPosts.get("tag.title"),
},
})
})
}
if (BlogCategorySlugs.length > 0) {
BlogCategorySlugs.forEach((BlogCategorySlug) => {
createPage({
path: `/category/${BlogCategorySlug}`,
component: BlogCategoryPostsTemplate,
context: {
group: BlogCategoryPosts.get(BlogCategorySlug),
slug: BlogCategorySlug,
title: BlogCategoryPosts.get("category.title"),
},
})
})
}
}
Where do I start?
I have tried upgrading packages, stripping out the config option in the config file, and deleting node_modules, package-lock.json and reinstalling the packages. I do run into errors when trying a normal npm i command, but that is fixed by adding the flag -legacy-peer-deps.
I also got this same error, but I got this after upgrading my WordPress plugins. Im pretty sure this is due to the new version 13.x of WP GraphQL. You can fix this by downgrading the WP GraphQL WordPress plugin to version 12.3. You can grab that v12 version here. Also more info on this issue and if a fix is implemented it will probably be updated here.
Had exactly the same issue.
Downgrading WP GraphQL to version 1.12.3 fixed this for me.
Here's the link wp-graphql.1.12.3

How to do pagination based on the document position within a collection? (offset pagination)

I'm trying to do a pagination where the user can see each button's page number in the UI. I'm using Firestore and Buefy for this project.
My problem is that Firestore is returning wrong queries for this case. Sometimes (depending the page that the users clicks on) It works but sometimes don't (It returns the same data of the before page button).
It's really messy I don't understand what's going on. I'll show you the code:
Vue component: (pay attention on the onPageChange method)
<template>
<div>
<b-table
:data="displayData"
:columns="table.columns"
hoverable
scrollable
:loading="isLoading"
paginated
backend-pagination
:total="table.total"
:per-page="table.perPage"
#page-change="onPageChange">
</b-table>
</div>
</template>
<script>
import { fetchBarriosWithLimit, getTotalDocumentBarrios, nextBarrios } from '../../../../firebase/firestore/Barrios/index.js'
import moment from 'moment'
const BARRIOS_PER_PAGE = 5
export default {
data() {
return {
table: {
data: [],
columns: [
{
field: 'name',
label: 'Nombre'
},
{
field: 'dateAddedFormatted',
label: 'Fecha aƱadido'
},
{
field: 'totalStreets',
label: 'Total de calles'
}
],
perPage: BARRIOS_PER_PAGE,
total: 0
},
isLoading: false,
lastPageChange: 1
}
},
methods: {
onPageChange(pageNumber) {
// This is important. this method gets fired each time a user clicks a new page. I page number that the user clicks.
this.isLoading = true
if(pageNumber === 1) {
console.log('show first 5...')
return;
}
const totalPages = Math.ceil(this.table.total / this.table.perPage)
if(pageNumber === totalPages) {
console.log('show last 5...')
return;
}
/* Here a calculate the next starting point */
const startAfter = (pageNumber - 1) * this.table.perPage
nextBarrios(this.table.perPage, startAfter)
.then((querySnap) => {
this.table.data = []
this.buildBarrios(querySnap)
console.log('Start after: ', startAfter)
})
.catch((err) => {
console.err(err)
})
.finally(() => {
this.isLoading = false
})
},
buildBarrios(querySnap) {
querySnap.docs.forEach((docSnap) => {
this.table.data.push({
id: docSnap.id,
...docSnap.data(),
docSnapshot: docSnap
})
});
}
},
computed: {
displayData() {
let data = []
this.table.data.map((barrioBuieldedObj) => {
barrioBuieldedObj.dateAddedFormatted = moment(Number(barrioBuieldedObj.dateAdded)).format("DD/MM/YYYY")
barrioBuieldedObj.totalStreets ? true : barrioBuieldedObj.totalStreets = 0;
data.push(barrioBuieldedObj)
});
return data;
}
},
mounted() {
// obtener primer paginacion y total de documentos.
this.isLoading = true
getTotalDocumentBarrios()
.then((docSnap) => {
if(!docSnap.exists || !docSnap.data().totalBarrios) {
// mostrar mensaje que no hay barrios...
console.log('No hay barrios agregados...')
this.table.total = 0
return;
}
const totalBarrios = docSnap.data().totalBarrios
this.table.total = totalBarrios
if(totalBarrios <= BARRIOS_PER_PAGE) {
return fetchBarriosWithLimit(totalBarrios)
} else {
return fetchBarriosWithLimit(BARRIOS_PER_PAGE)
}
})
.then((querySnap) => {
if(querySnap.empty) {
// ningun doc. mostrar mensaje q no hay barrios agregados...
return;
}
this.buildBarrios(querySnap)
})
.catch((err) => {
console.error(err)
})
.finally(() => {
this.isLoading = false
})
}
}
</script>
<style lang="scss" scoped>
</style>
The nextBarrios function:
function nextBarrios(limitNum, startAtNum) {
const query = db.collection('Barrios')
.orderBy('dateAdded')
.startAfter(startAtNum)
.limit(limitNum)
return query.get()
}
db is the result object of calling firebase.firestore(). Can I tell a query to start at a certain number where number is the index position of the document within a collection? If not, How could I approach this problem?
Thank you!
Firestore doesn't support offset or index based pagination. It's also not possible to tell how many documents the entire query would return without actually reading them all. So, unfortunately, what you're trying to do isn't possible with Firestore.
It seems also that you're misunderstanding how the pagination APIs actually work. startAfter doesn't take an index - it takes either a DocumentSnapshot of the last document in the prior page, or a value of the ordered field that you used to sort the query, again, the last value you saw in the prior page. You are basically going to use the API to tell it where to start in the next page of results based on what you found in the last page. That's what the documentation means when it says you are working with a "query cursor".

filter by category work not properly with remote search?

Hello I have problem compute vue filter by category it work not properly when I add item on Service tab and then click on Medicine tab remote search item by category it will stuck and filter not work and when I click in Service tab back it show only number 2.
this my template
<el-table
:data="itemFilters"
row-key="no"
style="width: 100%"
>
This my script
computed: {
itemFilters() {
const self = this
let item = self.form.items.filter(o => {
return o.categoryName === self.tabActive || o.itemId === ''
})
return item
},
},
this Method
methods: {
_getItemOpts(query, type) {
let exp = new RegExp(query)
let selector = {
$or: [
{ name: { $regex: exp, $options: 'i' } },
{ refNo: { $regex: exp, $options: 'i' } },
{ barcode: { $regex: exp, $options: 'i' } },
],
activityType: { $in: ['Sale'] },
status: 'Active',
'catDoc.name': this.tabActive,
}
// For form Sale Return and receipts refund
if (this.formName == 'Sale_Return' || this.formName == 'Receipt_Refund') {
selector.itemType = { $ne: 'Bundle' }
}
findItems
.callPromise({ selector: selector })
.then(result => {
// this.itemOpts = result
if (type == 'remote') {
// For remote
this.form.items[this.activeIndex].itemOpts = result
} else {
// For scan barcode
let item = result[0]
if (item) {
let row = {
itemId: item._id,
itemType: item.itemType,
memo: '',
qty: 1,
qtyRate: 1,
unitId: item.units[0].unitId,
units: item.units,
price: item.price,
amountBeforeDiscount: item.price,
discountRate: 0,
discountValue: 0,
amountAfterDiscount: item.price,
taxId: '',
taxAmount: 0,
// For expand bundle item
subItems: [],
expand: 'expand',
// For sales only(cash sales and invoice)
// refSaleOrderId: '',
// refSaleOrderDetailId: '',
// refNo: '',
itemOpts: result,
}
this.form.items.push(row)
} else {
Notify.warning({ message: 'This item do not set barcode!' })
}
}
this.loading = false
})
.catch(err => {
this.loading = false
this.$notify.error(err.reason)
})
},
}
Please help...

How do i convert a single json record retrieved from firebase into an array

I am trying to take a single record from firebase to use in vuejs but I cant find out how to convert it to an array, if thats even what i should be doing.
my mutation
GET_CASE(state, caseId) {
state.caseId = caseId;
},
My action
getCase ({ commit, context }, data) {
return axios.get('http' + data + '.json')
.then(res => {
const convertcase = []
convertcase.push({ data: res.data })
//result below of what is returned from the res.data
console.log(convertcase)
// commit('GET_CASE', convertcase)
})
.catch(e => context.error(e));
},
I now get the following returned to {{ myCase }}
[ { "data": { case_name: "Broken laptop", case_status: "live", case_summary: "This is some summary content", contact: "", createdBy: "Paul", createdDate: "2018-06-21T15:20:22.932Z", assessor: "Gould", updates: "" } } ]
when all i want to display is Broken Laptop
Thanks
Example let obj = {a: 1, b: 'a'); let arr = Object.values(obj) // arr = [1, 'a']
async getCase ({ commit, context }, url) {
try {
let { data } = await axios.get(`http${url}.json`)
commit('myMutation', Object.values(data))
} catch (error) {
context.error(error)
}
}
But as I'm reading your post again, I think you don't want array from object. You want array with one object. So, maybe this is what you want:
async getCase ({ commit, context }, url) {
try {
let { data } = await axios.get(`http${url}.json`)
commit('myMutation', [data])
} catch (error) {
context.error(error)
}
}
Put this inside / after your .then
Object.keys(data).forEach(function(k, i) {
console.log(k, i);
});
With a response from Axios, you can get your data as:
res.data.case_name
res.data.case_number
....
Just build JavaScript object holding these properties and pass this object to your mutation. I think it is better than using an array.
const obj = {};
Object.assign(obj, res.data);
commit('GET_CASE', obj)
And in your mutation you do as follows:
mutations: {
GET_CASE (state, payload) {
for (var k in payload) {
if (payload.hasOwnProperty(k)) {
state[k] = payload[k]
}
}
}
}
Alternatively you can code your store as follows:
state: {
case: {},
...
},
getters: {
getCase: state => {
return state.case
},
....
},
mutations: {
GET_CASE (state, payload) {
state.case = payload
}
}
and you call the value of a case field form a component as follows:
const case = this.$store.getters.getCase
..... = case.case_name

Meteor.js : SearchSource + Publish composite

I'm currently creating a research engine for my app.
Until now, I used Publish composite + iron router : The user could had filters to search for some specific set of users.
Now, I want him to be able to look for some keywords too. For that I downloaded and tested the great SearchSource package.
The problem is that the SearchSource server side definition only seems to allow to return one cursor.
How could I combine the two logics ? Even if it's tricky, please, share.
Of course I could make an autorunned subscription where I look for every users loaded on the client and then subscribe to the additionnal documents, but it is not really the most performant and beautifull thing to do.
Some data :
Here is my current Publish Composite for filters :
Meteor.publishComposite("findTalkers", function(page, langs){
//console.log("Find Talkers");
//console.log("page : " + page);
//console.log("langs : " + langs);
if (langs.length)
{
return ({
find: function()
{
if (langs && langs.length)
{
var test = {$in: langs};
preSelectedUsers = [],
selector = {
_id: {$ne: this.userId},
"profile.completed": true,
"profile.firstName": {$exists: true},
"profile.languages.native": {$exists: false},
"profile.languages.lang": test
};
Counts.publish(this, "nbUsers", Meteor.users.find(selector, {
fields: {_id: 1}
}), {noReady: false, nonReactive: true});
if (page > 1)
{
preSelectedUsers = Meteor.users.find(selector, {
sort: {'profile.talkname': 1},
limit: 25,
skip: (25 * (page || 1)),
fields: {_id: 1}
}).fetch();
var i = -1;
while (preSelectedUsers[++i])
preSelectedUsers[i] = preSelectedUsers[i]._id;
}
if (page > 1)
selector._id = {$in: preSelectedUsers};
return Meteor.users.find(selector, {
fields: userFields,
sort: {'profile.talkname': 1},
limit: 25
});
}
},
children: [
{
// Finding user's profile picture if it is not url
find: function(user)
{
if (user && user.profile && user.profile.avatar.type != "url")
return Images.find({_id: user.profile.avatar.data}, {sort: {uploadedAt: -1}, limit: 1});
}
}
]
});
}
else
{
return ({
find: function()
{
return Meteor.users.find({_id: "flush"});
}
});
}
});
Here is my research with SearchSource :
Client :
var searchOptions = {
keepHistory: 1000 * 60 * 5,
localSearch: true
},
SearchSources = {
talkersSearch: new SearchSource('users', ['profile.talkname'], searchOptions)
};
Router.map(function(){
this.route('talkers/:page?',
{
template: "talkers",
onBeforeAction: function(pause){
(Meteor.user() && Meteor.user().profile.completed)
? this.next()
: this.render('/profile');
},
waitOn: function(){
var filters = MatesFilter.find().fetch(),
i = -1;
while (filters[++i])
filters[i] = filters[i].value;
if (filters.length)
{
return Meteor.subscribe("findTalkers", (this.params.page || 1), filters, function(){
Session.set('numberuser', Counts.get("nbUsers"));
});
}
return Meteor.subscribe('myself');
}
});
}
Template.talkers.helpers({
getPackages: function() {
return SearchSources.talkersSearch.getData({
transform: function(matchText, regExp) {
return matchText.replace(regExp, "<b>$&</b>")
},
sort: {isoScore: -1}
});
}
}
Template.talkers.events({
"keyup #header-search": _.throttle(function(e) {
Session.set("matesSearch", $(e.target).val().trim());
console.log("Searching for : " + text);
SearchSources.talkersSearch.search(Session.get("matesSearch"), {
page: (this.params.page || 1),
filters: filters
});
}, 200)
}
SERVER :
SearchSource.defineSource('users', function(searchText, options) {
var options = {sort: {"profile.talkname": -1}, limit: 25};
if(searchText)
{
var regExp = buildRegExp(searchText);
selector = { $or: [
{ "profile.talkname": regExp },
{ "profile.bio": regExp }
] };
return Meteor.users.find(selector, options).fetch();
}
return ;
});
All this Gives me two sources from which I can get users. I'd want to get a mean to merge the two ides (a composition of publication INSIDE the search, for example).
Thanks you.

Resources