Vue tables 2 setPage method not working after used fetchMore - vue.js

I'm trying to use setPage method of vue-tables-2 library after used fetchMore from vue-apollo, But the issue its when the query get the new result, the table it's still on the first page
mounted: function(){
var ref = this
Event.$on('vue-tables.pagination', function(data) {
ref.showMore()
ref.$refs.table.setPage(data)
})
},
Vue-tables-2

I think vue-tables.pagination event is not working properly for your code.First of all you have to create one data property which will store your current page.Store number of page on which you performed your last action.Then set page to that data property.

SetPage takes in number of the page, not page data.

Related

allowed-dates attribute in Vuetify date picker is not responsive

I have a web page that displays a Vuetify date-picker component.
When the page is loaded or when the month is changed, I make an AJAX call that runs an SQL query to return the dates in that specific month when a particular event occurred.
Then, I only want to make these specific dates clickable.
As per the Vuetify documentation, the allowed-dates attribute allows you to do this.
After some experimentation, I have come across some unexpected difficulty:
The allowed-dates attribute takes in a function instead of, for example, an array. So, I had to create a function that will consult an "allowed dates" array that is returned by my AJAX call
Furthermore, the function is called when the date-picker is rendered and NOT when the AJAX call returns, so I end up with no dates being activated or only one date being activated on only the last date of the month being activated.
Am I missing something? is the allowed-dates attribute not responsive? I would prefer to stick with Vuetify since I am using it for the rest of the UI, but I am willing to switch to something else if a solution cannot be found.
There's some confution when an example in docs says:
You can specify allowed dates using arrays, objects, and functions.
But in API allowed-dates consumes only functions.
I guess the answer is to correctly define allowedDates function.
You first need to create an empty reactive array, then assign data into it via AJAX call, and in allowedDates function you just be able to compare the displayed page of dates with the dates in the array.
So the code is...
<v-date-picker
v-model="date"
:allowed-dates="allowedDates"
/>
...
data: () => ({
date: '2022-01-11',
allowedDatesArray: [],
}),
mounted() {
this.getAllowedDates();
},
methods: {
allowedDates(val) {
return this.allowedDatesArray.includes(val);
},
async getAllowedDates() {
this.allowedDatesArray = [];
await //...your AJAX call that must assign allowedDatesArray
}
}
I created a sandbox at CodePen where you may test this solution with some static dates that loading asynchronously using Promise.
In your solution you need to replace Promise with your AJAX call.

Vue 3 composition API, undefined variable, lifecycle

I am quite new to Vue.js and while developing my first project i have stumbled upon a problem which I think is related to the component's lifecycle.
The context is the following:
I am using Vue 3 with composition API.
I have a "Map" component in which I use d3.js to show a chart.
In my Setup() method I have onBeforeMount() and onMounted().
In onBeforeMount() method, I want to use data from my Firestore database for the values in the chart. The console.log on line 47 shows the data correctly.
In onMounted(), is where I plan to put my d3 chart. But when I try to access the data as in console.log on line 55, I get undefined...
Ideally, from "Map" component, I want to fetch the data from my database and use it in order to create the chart and then have the component render the chart.
Then I would have another component called 'MapSettings" that will be able to alter the data in "Map" such as filters etc...and have the values automatically updated in the chart.
Finally, both components will be siblings and have same parent component. So "Map" and "MapSettings" are on same hierarchical level.
But first I need to understand why I am getting undefined.. Any help or suggestion would be greatly appreciated!
Your lifecycle hooks look nice. The problem that you're facing has to do with code been executed asynchronously and code been executed synchronously.
You're declaring a function that uses async-await feature. This function will be executed asynchronously. In this case, you're getting data from Firestore and storing it in a ref at onBeforeMount().
On the other hand, you're declaring a normal function at onMounted() trying to access a ref's value, which will result in undefined because the function that you define at onBeforeMount() didn't finish its execution (or it's in the event queue) when onMounted is called.
That's why you first see the console.log that comes from onMounted.
One solution would merge both functions in one lifecycle hooks and use async await:
setup() {
const {actorDocs, load} = getActorDocs()
const actorsData = red([])
// load actor data from db
onBeforeMount( async () => {
await load()
actorsData.value = actorDocs
console.log(actorsData.value)
// manipulate it here...
})
}
Keep in mind that you cannot pause with async-await a lifecycle hook. What you're pausing is the function that Vue will execute in that hook. Indeed, this is really nice because pausing a hook wouldn't be efficient at all.
i face that problem, in my case i want use imgsRef.value out of onBeforeMount scope. How to get imgsRef value out of beforeMount scope?
onBeforeMount( async () => {
await axios
.get("http://localhost:3000/ourMoment")
.then((response) => {
imgsRef.value = response.data
// imhsRef get the value from api
console.log(imgsRef.value.photo)
})
})
// i try to concole.log here but the value still empty
console.log(imgsRef.value)

Vue.js table updating component data without re-rendering whole component on selected filters

I have a single page dashboard application. I've been playing around with setInterval which works quite well for just updating the data without reloading the page. I put the setInterval function within mounted(), not sure if it best belongs there but works okay.
However! This SPA has a ton of filters. You can search, you can select dropdowns, you can sort, on and on. Say the initial page load has 1000 rows and you use the search bar to narrow it down to one row/one result. Now setInterval runs and it will re render all 1000 rows. This is the method (defined in methods: {} section that initially loads the data and the method used in mounted() with setInterval):
getData: function (arg1, arg2) {
API.getSomeData(arg1, arg2).then(resp => {
getTicketData(resp.data);
this.$data.loading = false;
});
}
Is there a way to account for the filters when it comes to the setInterval piece?
Any and all insight is appreciated.
It sounds like you might be overwriting the same data property when you fetch data from the API and when you filter on it. If that's the case, you should use a computed property to display the filtered records to the user instead.
computed: {
tableRows() {
if (this.filters)
return this.filter()
return this.apiData
}
Where this.filter() will filter down this.apiData without overwriting its contents. Then you can iterate over tableRows in your template (e.g. v-for="row in tableRows") to display those to the user.
If you want to remove some of this logic from your Vue component, you might consider using a Vuex store to both fetch/update from your API and also to calculate the filters.
this.$store.dispatch('fetch_on_interval', { interval: 1000 })
this.$store.dispatch('set_filters', { ...filters })
this.$store.getters('table_data')
Your getter would check the filters and return whatever is relevant. Vuex getters can be used in computed properties too.

Computed value based on component's created method

In my component I have acreated method where I make a request and then I want to use the data I get for a computed property.
computed: {
...mapState(["pages"]),
pageContent() {
let slug = this.$route.params.slug ? this.$route.params.slug : 'home' ;
let page = this.pages.find(page => page.slug == slug);
return page.content;
}
},
methods: {
...mapActions(['setPagesAction'])
},
created() {
this.setPagesAction();
}
The problem is that created is executed after the computed property pageContent is read, so it is undefined.
How can I make pageContent get the data from created ?
Solution
As you know, computed property will update itself when the dependent data changes. ie when this.pages is assigned in vuex. So
You have mainly three options.
Option 1
Set a variable so that till the time page content is being loaded, a loading spinner etc is being shown.
Option 2
If you are using vue-router, then use the beforeRouteEnter guard to load the data.
like here
Option 3
Load data initially (when app starts) and add it to vuex. (you can use vuex modules for seperating data store if needed)

Watch for URL query parameter in Vuex store

I am using Nuxt.js with Vuex and I would like to trigger a mutation when somebody enters in my web with a certain parameter (ex: https://example.com/?param=abc), and pass the parameter to a state.
I tried to check the documentation of the watchQuery property https://nuxtjs.org/api/pages-watchquery, but there’s no examples about how to do this, I just found this How to watch on Route changes with Nuxt and asyncData but I can’t see any way of how to write an action in Vuex store with watchQuery.
I tried writing:
actions: {
watchQuery: true,
asyncData ({ query, app }) {
const { start } = query
const queryString = start ? `?start=${start}` : ''
return app.$axios.$get(`apps/${queryString}`)
.then(res => {
commit('setParam',res.data);
})
},
}
But that syntax is not allowed.
Any help would be welcome, thanks in advance!
From my understanding watchQuery sets a watcher for query string, meaning it's waiting for the query to change while the page is already rendered making it possible to call methods like asyncData() again.
Since you only want to save a certain parameter when the user enters the page and then pass the paramater to a state you just need to move your asyncData method to a page from which you want to get the parameter, you will also need to extract store and query from the context automatically passed into asyncData and then using the store and query save the query parameter into your state.
Here is a simple demonstrantion
// Your page from which you want to save the param
export default {
asyncData({store, query}) { // here we extract the store and query
store.state.somethingForSavingTheParam = query.nameOfTheParamYouWantToSave
// instead of using store.state you could use store.commit(...) if that's what you want
}
}