VueJs get url query - vuejs2

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

Related

NUXT pass object data into pages with path

I'm really new to Vue and Nuxt so I apologise if this is a simple question.
I'm generating my routes dynamically on making an API call for my data on Index.vue. One API call is enough for me to retrieve all the data i need which is stored in deals_array, so I don't need another API call on my individual page, I just need the data from each deal in deals_array.
<ul>
<li v-for="deal of deals_array" :key="deal.id">
<nuxt-link :to="getSlug(deal)">{{ deal.name }}, {{deal.value}}</nuxt-link>
</li>
</ul>
I'm wondering how do I pass the entire deal object into my pages, so that when I click on the individual nuxt-link I would be able to access that deal object and all its attributes (for each page).
I've taken a look at passing params into nuxt-link but I understand that it only pairs with name attribute and not the path, where I need the path URL in this case.
I may be doing this entirely wrong so I'm hoping to be pointed in the right direction.
Edit - getSlug function
getSlug(deal) {
let name = deal.name;
let dealDetails = deal.details;
let name_hyphen = name.replace(/\s+/g, "-");
let deal_hyphen = dealDetails.replace(/\s+/g, "-");
let nameDealSlug = name_hyphen + "-" + deal_hyphen;
// remove selected special characters from slug
let clean_nameDealSlug = nameDealSlug.replace(
/[&\/\\#,+()$~%.'":*?<>{}]/g,
""
);
let finalSlug = `deals/${clean_nameDealSlug}`;
return finalSlug;
}
I'm assuming you have gone through this: https://router.vuejs.org/api/.
You can just pass the entire object:
<nuxt-link :to="{ path: 'test', query: {a: 1, b: 2}}">Test Page</nuxt-link>
And your URL will become something like this:
http://localhost:3000/test?a=1&b=2
The entire object can be simply passed.
This will be available to your next page in $route object in the url query.
Otherwise if you don't want to get your deal object exposed just use the concepts of vuex. Store the entire deal object in the vuex and pass ids to different pages. And from pages retrieve the deal object through vuex.

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 .

vuejs this.$route issue with address bar

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' })

$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)

Pass values to route

I have a list of items. When the user clicks on an item, the user will be taken to item details page.
I want to pass an object containing item details(like item's image URL) to the route. However, I don't want to expose it in the routes url.
If there were a way to do something like <a route-href="route: details; settings.bind({url: item.url})">${item.name}</a> that would be gold.
I have seen properties can be passed to a route if defined in the route configuration. However, I don't know how to change that from the template. Another way could be is to define a singleton and store the values there and inject the object to the destination route.
Is there a way to pass values to routes from view (like angular ui-routers param object)?
Okay so I figured out a way to achieve something closer to what I wanted:
Objective: Pass data to route without exposing them in the location bar.
Let's say, we have a list of users and we want to pass the username to the user's profile page without defining it as a query parameter.
In the view-model, first inject Router and then add data to the destination router:
goToUser(username) {
let userprofile = this.router.routes.find(x => x.name === 'userprofile');
userprofile.name = username;
this.router.navigateToRoute('userprofile');
}
Now when the route changes to userprofile, you can access the route settings as the second parameter of activate method:
activate(params, routeData) {
console.log(routeData.name); //user name
}
For those #Sayem's answer didn't worked, you can put any additional data (even objects) into setting property like this:
let editEmployeeRoute = this.router.routes.find(x => x.name === 'employees/edit');
editEmployeeRoute.settings.editObject = employeeToEdit;
this.router.navigateToRoute('employees/edit', {id: employeeToEdit.id});
So editObject will be delivered on the other side:
activate(params, routeConfig, navigationInstruction) {
console.log(params, routeConfig, navigationInstruction);
this.editId = params.id;
this.editObject = routeConfig.settings.editObject;
}
hopes this helps others encountering same problem as me. TG.