Vue router change query on current route - javascript

I have a URL I'm appending attribute parameters to using this code:
this.$router.push({ query: Object.assign({}, this.$route.query, { attributes: this.encodedAttributes() }) });
When I call that method the second time, the parameters get added again. But I want it to update rather than adding another time if there are already attribute parameters. Any help is highly appreciated.

(Referring to the code link in comments) Putting a stringified array into a query param will not convert it to query params. It's also part of a nested object which also wouldn't work.
Make dynamic_fields an object:
data() {
return {
dynamic_fields: {},
};
},
Remove encodedAttributes and change search:
search() {
this.$router.push({ query: this.dynamic_fields })
.catch(failure => false);
}
.catch on $router push prevents the navigation failure error.
Here is an updated sandbox

Related

How do I mask the route path in vue while passing data through params?

I managed to pass an object through params. However, how do I mask the information in the url shown above?
Here's the code where I pushed the object through using params into another page called 'Staff Profile'.
This is the path when I added the parameter.
Copied from the vue-router change log:
Putting the data in a store like pinia: this is relevant if the data
is used across multiple pages
Move the data to an actual param by defining it on the route's path
or pass it as query params: this is relevant if you have small
pieces of data that can fit in the URL and should be preserved when
reloading the page
Pass the data as state to save it to the History API state:
<router-link :to="{ name: 'somewhere', state: { myData } }">...</router-link>
<button
#click="$router.push({ name: 'somewhere', state: { myData } })"
>...</button>
Note state is subject to History state limitations.
Pass it as a new property to to.meta during navigation guards:
router.beforeEach(async to => {
if (to.meta.shouldFetch) {
// name `data` whatever you want
to.meta.data = await fetchSomething()
}
})
This is known an transient state and since it's in a navigation guard, it will be preserved when reloading the page. Check the documentation for more details.
Below is the original answer but was removed from vue-router#4.1.4 and is advised against being used
this.$router.push({name:"Staff Profile",params:{
id:users[user.sNo-1].staffID,
staffData:JSON.stringify(users[user.sNo-1])
}})
Passing parameters like this will use the value of id to show in the url and pass the other props in the background.
In this case the url will look like /staffProfile/1001A
And you can access the staffData object in the routed view like this.
//Staff Profile.vue
this.$route.params.staffData

How to Reload to same Page while sending a parameter?

I need to reload the page whenever different buttons are pressed, while sending a String to the same page so that on created() it takes that String and sends an HTTP Get into my Database.
Currently I have the following:
export default {
data(){
return{
events: [],
formData:{
sportType: 'Ténis'
}
}
},
created(){
//Do something here to get the value sent from the reloading
axios.get(`http://localhost:8001/evento`, {headers: {sportType: this.formData.sportType}})
.then((response)=>{
this.events = response.events
},(error) =>{
console.log(error);
});
},
pickSport(item){
}
The function pickSport() is called whenever the buttons are pressed and each sends a value to this function that is a String. The idea now is to be able to reload the page when this function is called, while sending this item to the reloaded page, so I can update the value of sportType. I tried:
pickDesporto(item){
this.$router.push({
path: '/betting',
params: item
});
}
But with no success, since it keeps giving me a NavigationDuplicated error. How can I solve this?
They are many way to do this. You may want to use Watch: {} to keep track of certain parameter. It will be trigger once the parameter change and you can re-render the same page with new parameter.
There is also a way called key-binding but it need to bind the key to the component. I personally suggest this one because it will be easy to understand.

Changing a parameter in Vue 3 router

I was trying to change a route parameter with Vue router.
My route is the following :
/document/:id?/:lang?/edit
Id and lang (language) are the parameters.
I want to change the parameter lang using JavaScript without altering the rest of the route. I tried applying the following solution (found here). The solution was made for Vue 2 and not 3. So I tried to make an updated version.
This is my code :
let params = this.$route.params
params.lang = 'en'
this.$router.push({params:params})
When I execute my code, there is no change in the route parameters nor an error logged in the console. Does anyone know a solution to this problem in Vue 3.
Thanks in advance.
It's a bad way to change your route parameter like this.
Instead, replace your route with the same name, same id, but different lang:
this.$router.replace({
name: this.$route.name,
params: {
id: this.$route.params.id,
lang: 'en' // or whatever you want
}
})
Don't forget to watch for the route changes if needed:
watch: {
$route(to, from) {
// if anything needs to be done when the route changes
}
}

Referencing GraphQL variable used in query in Gatsby template?

I am aggregating all posts that have a certain tag in it's tag list:
export const Search = graphql`
query SearchResults($tag: String = "") {
allMarkdownRemark(filter: { frontmatter: { tags: { in: [$tag] } } }) {
nodes {
frontmatter {
title
date
}
}
}
}
`
The query works great, but I want to also be able to dynamically show the tag that is being queried for. How can I pass this information through?
For example: Searching results for tag: Java which would be the value inside $tag in the graphql query.
I tried to pull from the URL, but it's rendered in node, so I don't have access to the window object and it felt a bit hacky anyway.
I got it. Passing in props.pageContext gives you access to the contextual information passed in via gatsby-node.

Firestore, vue, vuex, vuexfire: How to make getter actually get data from store?

If I want to query documents from a Firestore with Vuexfire. I can successfully do this by doing the following:
I can bind the docs using this action:
bindEntries: firestoreAction(({ bindFirestoreRef }) => {
var query = db
.collection("entries")
.orderBy("date");
return bindFirestoreRef("entries", query);
}),
that I dispatch in my App.vue like this:
created() {
this.$store.dispatch("bindEntries");
},
To actually get the data in my component, I use this getter
entries(state) {
return state.entries;
},
that I call in a computed property:
computed: {
entries() {
return this.$store.getters.entries;
},
}
So far, so good.
Now I want to adjust my code to not query all the data from the Firestore, but filtered for the currently logged in user. I adapted the firestoreAction to
bindEntries: firestoreAction(({ bindFirestoreRef }, uid) => {
var query = db
.collection("entries")
.where("editors", "array-contains", uid)
.orderBy("date");
return bindFirestoreRef("entries", query);
}),
and moved the dispatching part to the point where the user successfully logged in. It is not in the created hook of the App.vue. I moved it, because the user id is unknown in the created hook. I call it like so:
auth
.signInWithEmailAndPassword(this.email, this.password)
.then((data) => {
this.$store.dispatch("bindEntries", data.user.uid);
}
I'm not geeting any errors, but nothing is displayed. What am I doing wrong?
I uploaded the whole code, in case I forgot to mention something: https://github.com/juliangermek/haushaltsbuch
Thanks a lot!
Edit:
I just found out that in another component (in Stats.vue > MonthOverview.vue > OverallSums.vue) everything looks fine!
The only difference I can see is that I redirect directly to Entries.vue (the page I'm having problems with) and switch to the stats afterwards as a user. I just switched this in my router and my Entries.vue looks just fine! Now it is the stats that throws an error due to missing data. How could this be explained?
With your query, which combines a where clause with array-contains and an orderBy clause you need to create an index.
More details in the doc:
https://firebase.google.com/docs/firestore/query-data/order-limit-data
https://firebase.google.com/docs/firestore/query-data/queries#in_not-in_and_array-contains-any
https://firebase.google.com/docs/firestore/query-data/indexing

Categories