vuejs this.$route issue with address bar - vue.js

When I remove a parameter, It does not take effect in address bar.
I tried following line to remove parameter from URL.
delete this.$route.query[parameter_name];
See below url, Notice following things.
In console query object is empty but address bar having all parameters.
I tried following lines to remove applicants and branches parameters from URL. It only effected in console as you can see query object is empty but URL is still there.
delete this.$route.query['applicants'];
delete this.$route.query['branches'];
But still address bar is having all removed params.
donate#/?applicants=Female&branches=2207962

Using delete will delete the property but will not update the address bar.
You need to specify a redirect programmatically. See Programmatic Navigation.
You can use
this.$router.push('donate')
Or
this.$router.replace('donate')
to replace the current history entry (see comment from #thanksd)

This will work with $router.push or $router.replace to clear the query string.
Clear the query string inside a component lifecycle hook.
mounted() {
this.$router.replace({ query: { '': null } });
}
Clear the query string on redirect.
$router.push({ path: 'url-path', query: { '': null } })
$router.replace({ path: 'url-path', query: { '': null } })
Remove old query string values and replace with new values.
$router.push({path: 'url-path', query: {'': null, lastname: 'Ever', firstname: 'Greatest'}})
$router.replace({ path: 'url-path', query: { '': null token: 'coolToken' })

Related

NuxtJS change query params and reload page

I have a route in my NuxtJS application that accept query parameters. I'm trying to implement a logic that allow the user to change the query parameters and reload the page.
I tried:
// this does not work because I'm already in "mypage" and "push" does not reload the same page
this.$router.push(`/mypage?param1=${value1}&param2=${value2}`)
// same result as above
this.$router.push({ path: '/mypage', query: {param1: value1, param2: value2}})
// this is able to change the query parameters but on reload they are reverted to the originals
this.$router.replace({ query: {param1: value1, param2: value2} })
window.location.reload()
// This reload the page but the query parameters are reverted as well
this.$router.go(`/mypage?param1=${value1}&param2=${value2}`)
Any suggestions?
You should use the 2nd method to update query params.
this.$router.push({ path: '/mypage', query: {param1: value1, param2: value2}})
It's really a bad practice to force reload a page, instead, you should set up a watcher or a computed for your query.
E.g.
watch: {
'$route.query'() {
// do something
}
},
If this doesn't work for your please provide more information about your problem.
This is only a workaround:
thanks to this: https://github.com/vuejs/vue-router/issues/1182#issuecomment-405326772
I was able to work around the issue by using javascript:
window.history.pushState({},'',`/mypage?param1=${value1}&param2=${value2}`)
window.location.reload()
of course this is not an optimal solution but it gets the work done until someone come out with a more proper solution here. thanks.
You can do it use promise.then() and $nuxt.refresh()
// before
this.$router.replace({ query: {param1: value1, param2: value2} })
window.location.reload()
// after
this.$router.replace({ query: {param1: value1, param2: value2} }).then(() => {
this.$nuxt.refresh();
});
if u want only to change query param without reloading the page, use Fabio Magarelli solution:
window.history.pushState({},'',`/mypage?param1=${value1}&param2=${value2}`)
for change with reload - use this:
this.$router.push({path: this.$route.path, query: { param1: 'param1', param2: 'param2' }})
Use watchQuery
export default {
watchQuery: ['page']
}
Doc: https://nuxtjs.org/docs/components-glossary/watchquery/#the-watchquery-property

Vue: Setting Data by matching route query

I'm attempting to set data fields provided by an array based on the Vue Router query. For example, when someone lands on my website using example.com/?location=texas, I want to set the location data by an array.
An example the array:
locations {
{
slug: "texas",
tagline: "Welcome to Texas",
}, {
slug: "california",
tagline: "Welcome to California",
}
}
I know this should be done using a computed property, however I am unable to get anything functioning. I've tried simple tests like if (this.slug.location === "texas"), and I cannot get the location data to populate. I would also like to provide default data in case there are no route matches.
Any help is extremely appreciated!
Edit:
I can accomplish this in a very manual way. Right now, I'm setting the query in data by the following:
slug: this.$route.query.location
I can display specific text by doing something like:
h3(v-if="slug === 'texas'") This will show for texas
h3(v-else-if="slug === 'california'") This will show for California
h3(v-else) This is default
The issue with this approach is there are various elements I need to customize depending on the slug. Is there any way I can create an array, and move whichever array matches a key in an array to the data??
You should be able to access a query param using the following (link to Vue Router documentation):
this.$route.query.location
So based on what you listed I would do something like...
export default {
computed: {
displayBasedOnLocationQueryParam() {
switch(this.$route.query.location) {
case 'texas':
return 'Welcome to Texas'
default:
return 'hello there, generic person'
}
}
}
}
Note that I'm not using your array explicitly there. The switch statement can be the sole source of that logic, if need be.

vue-router query parameter as array with keys

I need to generate a vue-router link that contains an array with string keys as a query parameter.
I want the resulting URL to look like
url?param[key]=value
I need these kinds of query parameters to match an existing backend infrastructure, so renaming/refactoring them is not an option.
I've tried to use a router-link like the one below, but the param object just get's serialized as %5Bobject%20Object%5D. Maybe there is an option to change the way this object is serialized within vue-router?
<router-link :to="{name: 'xyz', query: {param: 'value'}}">link</router-link>
Does anyone have helpful input? Thank you :)
After spending some time vue-router GitHub issues and their docs, I figured it out.
When creating your RouteConfig, import qs and set the parseQuery and stringifyQuery methods as follows:
parseQuery: (query: any): object => {
return qs.parse(query);
},
stringifyQuery(query: any): string {
let result = qs.stringify(query, {encode: false});
return result ? ('?' + result) : '';
}
It is important to include {encode: false}, otherwise the square brackets will get URL encoded.
Addition to Martin's comment,
Exact Router config should be :
// https://github.com/ljharb/qs
import qs from 'qs';
const router = new Router({
routes: [
// ...
],
// set custom query resolver
parseQuery(query) {
return qs.parse(query);
},
stringifyQuery(query) {
var result = qs.stringify(query);
return result ? ('?' + result) : '';
}
});
and query parameters inside routes will be automatically converted url string and parsed as an object when accessing $router.query .

$router.replace() doesn't update browser query string

The problem is that the query string does not show up in the browser's URL bar.
The code updates the query string in order to keep track of a product configuration.
There are two methods - the first one chooses the model and the second one sets options for that model. Here's the code (the values for the query string are placeholders now):
Methods:
chooseModel (option) {
this.$router.replace({
path: this.$route.path,
query: {m: 'model'},
})
},
choose (option) {
if (!this.selectedModel) return
let opt = {}
opt[option] = option
this.$router.push({ // I've tried push and replace
path: this.$route.path,
query: Object.assign(this.$route.query, opt),
})
},
Computed:
selectedModel () {
return this.$route.query.m
},
When chooseModel is invoked the query string that the browser displays shows up as it should: http://localhost:8080/custom/?m=model. But when choose is invoked the query string that the browser displays remains the same.
FWIW, I have changed the code in chooseModel to set multiple query string values and they all show up. Apparently it is trying to modify that value that causes problems.
Using the debugger I can see that $route.query is correct - it reflects the changes I've made to the query.
I seen the same behavior with both Firefox and Chrome, so it apparently isn't browser-specific.
What do I need to do to get the browser to display the updated query string?
This is my bug but strange behavior nonetheless.
Because a route is immutable Object.assign() is not able to modify it. What is odd is that after my attempt to modify the query string the new route object showed the values I was attempting to set even though the browser didn't display them.
The fix is simple - don't try to modify the route object:
query: Object.assign({}, this.$route.query, opt)
(thanks VCavallo for new link location)

VueJs get url query

I'm developing a website with vuejs and at this moment I'm with a problem, I need to get the URL query (page) from a URL like this websitename.com/user/?page=1 but the this.$router.query.page gives me an error (Uncaught TypeError: Cannot read property 'page' of undefined)
Does someone know something about this problem and can help me?
PS: I can set the query page using
this.$router.push({name: 'userIndex', query: { page: '123' } });
and I can get the URL normal params like the
userID -> (websitename.com/user/:userId | websitename.com/user/1)
but I can't get any query parameter.
I think you can simple call like this, this will give you result value.
this.$route.query.page
Look image $route is object in Vue Instance and you can access with this keyword and next you can select object properties like above one :
Have a look Vue-router document for selecting queries value :
Vue Router Object
You can also get them with pure javascript.
For example:
new URL(location.href).searchParams.get('page')
For this url: websitename.com/user/?page=1, it would return a value of 1
Current route properties are present in this.$route, this.$router is the instance of router object which gives the configuration of the router. You can get the current route query using this.$route.query
In my case I console.log(this.$route) and returned the fullPath:
console.js:
fullPath: "/solicitud/MX/666",
params: {market: "MX", id: "666"},
path: "/solicitud/MX/666"
console.js: /solicitud/MX/666
For the url either having query param or as route path. use: this.$router.currentRoute._value. It has all the properties of the url that you may want
This is have all the routes like for url: https://localhost:8880/2?isExternal=true
this.$router.currentRoute._value.params.studentId
note: studentId is the route param name.
output: will return 2
This is have all the query params like: https://localhost:8880/2?isExternal=true
this.$router.currentRoute._value.query.isExternal
output: will return value of isExternal, that is: true