How to remove query from vue router? - vuejs2

All the tries to remove query string fails
// Initial state
this.$router.replace({
name: 'routeName',
query: {
param: 123
}
});
// Errors
this.$router.replace({ query: {}});
this.$router.replace({ query: undefined });
this.$router.replace({ query: null });
How to remove query without any errors?
Vue-router v3.1.5

For some reason router.replace() & router.push() need a non-empty object as query. So all rest to do is clean your initial query object from values, like:
let query = {
param: [1, 2, 3]
};
// Initial state
this.$router.push({
name: 'yourRouteName',
query: query
});
// clean your initial query object
query.param = [];
// Now replace it
this.$router.replace({
query: query
});

Vue 3
This worked for me:
import { useRoute, useRouter } from 'vue-router'
// put this inside your setup() function:
const route = useRoute()
const router = useRouter()
if (route.query.username = 'test') {
// do stuff...
// clear the query
router.replace({ query: {} })
}

Try this code:
let query = Object.assign({}, this.$route.query);
delete query.param;
this.$router.replace({ query });

Related

Unable to fetch query parameter in NextJS

I have an API route /api/form
// ./pages/api/form.js
import Router from 'next/router';
...
export default async function handler(req, res) {
...
res.redirect(307, '/summary?username=username');
Router.push({
pathname: '/summary',
query: {
username: username
}
});
}
// ./pages/summary.js
import { useRouter } from 'next/router';
export default function Summary() {
const router = useRouter();
console.log(router.query); // undefined
}
I am not able to fetch the query param. Also, if change the order of Router.push and res.redirect, I still stay on the /api/form route
I also tried using useRouter().push as per the documentation. Still, I stay in the /api/form route.
How to get the query param?
next/router allows you to do client-side transitions: https://vercel.fyi/next-router-client-side
For your use case I suggest putting the router.push event inside your form submit event, something like this:
<form
onSubmit={() => {
fetch(`/api/form`, {
...
}).then((res) => {
if (res.status === 200) {
router.push({
pathname: '/summary',
query: {
username: username
}
})
}
)
}
}
>
...
</form>

Adding default query to all router links in Vue?

I'm trying to find a way to add default query to all router-links on a page (in all components that it has)?
For example, I want all links on a page to end with argument: utm_campaign=from_our_friends.
And this page uses components that are also used by other pages.
You can add a navigation guard to the page component that adds an extra query param to the next destination:
beforeRouteLeave(to, from, next) {
const query = { ...to.query, utm_campaign: "from_our_friends" };
next({ query });
}
Based on the answer by #Majed Badawi, I ended up applying this solution:
beforeRouteLeave(to, from, next) {
const query = {
...to.query,
utm_campaign: 'from_our_friends'
};
if (!to.query.utm_campaign) { // otherwise you'll get 'infinite redirection' error
next({ path: to.path, query });
} else {
next()
}
}

Why is 'route.params.id' unavailable/undefined in setup method?

I'm working with vue-router and Vue 3. I have a view where I'd like to take the router url and use it to call a method to access an API. This method returns a promise I can use to populate my page. When calling my method with 'route.params.id', it says that the parameter is undefined. When I do console.log(route.params.id), it displays correctly in console. I've tried using a computed property instead, but I had the same issue.
Setup code:
import { ref } from "vue";
import MovieApiService from "../api/MovieApiService";
import { useRoute } from "vue-router";
export default {
setup() {
const movie = ref([]);
const route = useRoute();
MovieApiService.getMovie(route.params.id).then((response) => {
movie.value = response.data.results;
});
return {
movie,
};
},
method: {},
};
Method being called:
static getMovie(body: GetMovieByTmdbId) {
return axios.get(
`https://api.themoviedb.org/3/movie/${body.id}?api_key=${apiKey}`
);
}
Here's what I tried to compute the property instead, with the same result.
setup() {
const route = useRoute();
const id = computed(()=>{return route.params.id})
const movie = ref([]);
getMovie(id).then((response) => {
movie.value = response.data.results;
console.log(movie.value);
});
How should I ensure this value is available when I call my method?
You are giving route.params.id as a variable to getMovie(body).
You are then using body.id in your URL. This would equal route.params.id.id which is not defined.
Use body in your URL, or change the parameter to id so is makes more sense.
Like this:
...
const route = useRoute();
MovieApiService.getMovie(route.params.id).then((response) => {
movie.value = response.data.results;
});
...
const getMovie = (id) => {
return axios.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${apiKey}`
);
}

How to use Nuxt Context to call Axios request with param

so I'm trying to get my Axios to do a get request with a param that'll end the url in
'/?user= {id}'
the id is passed in by my loggedInUser.id from Vuex. I know that async functions won't accept 'this' inside the call so I included store as a parameter. Something's still off with how I passed the data around thought I think. Would appreciate any help, thanks!
import { mapGetters } from "vuex";
export default {
computed: {
...mapGetters(["loggedInUser"])
},
head() {
return {
title: "Actors list"
};
},
components: {
EditProfile
},
async asyncData({ store }) {
try {
const body = { data: store.getters.loggedInUser.id };
const { actors } = await $axios.$get(`/api/v1/actors/`, {
params: {
user: body
}
});
return { actors };
} catch (e) {
return { actors: [] };
}
},
data() {
return {
actors: []
};
Edit
I got it to work when I removed the data: from 'const body' and removed the brackets as well around 'actor'
try {
const body = store.getters.loggedInUser.id;
const actors = await $axios.$get(`/api/v1/actors/`, {
params: {
user: body
}
});
You can access your params from Context.
Context is available in special nuxt lifecycle areas like asyncData, fetch, plugins, middleware and nuxtServerInit.
In Nuxt, with asyncData hook you can get query parameters from the route context key.
Please read the Nuxt.js Context documentation. The context provides additional objects/params from Nuxt to Vue components
With your-domain/?user=wonderman
asyncData({ route: { query: queryParams} }) {},
variable queryParams is an object:
{ user: "wonderman" }

Params field is empty in $router.push

Consider this:
this.$root.$router.push({
path: '/dashboard',
params: { errors: 'error' },
query: { test: 'test' }
})
I use this in my component to redirect to another URL, and some error has occured. The problem is that when I want to access params field in dashboard component, it's empty. The query field works well. I'm trying to access it by this.$route.params.errors.
You can use params only with named paths (i think).
Example:
//route (in your router file should have "name")
{ path: '/errors', name: 'EXAMPLE', component: ... }
//navigating
this.$router.push({
name: 'EXAMPLE',
params: { errors: '123' }
});
Now it will have correct value in this.$route.params.
If you don't want to use named routes you can try this:
ES6
this.$root.$router.push({
path: `/dashboard/${error}`,
query: { test }
})
ES5
this.$root.$router.push({
path: '/dashboard/' + error,
query: { test: 'test' }
})
I faced the similar issue where in one of my views (component). I was trying to navigate (programmatically) from /foo/bar to /foo/bar/123, but the route param was not available later in the component. My relevant navigation code looked like below:
methods: {
save_obj() {
let vm = this;
// Make AJAX call to save vm.my_obj, and on success do:
let v = `${vm.$route.path}/${vm.my_obj.id}`;
console.log("Loading view at path: "+v);
vm.$router.push({ path: v });
},
...
}
It would print the expected log (e.g., Loading view at path: /foo/bar/112), however, the loading of data in the created() hook would not receive the value of route param. My failing created() code looked like below:
created: function() {
console.log("Loading object details.");
let vm = this;
let cid = vm.$route.params.id; // <---- This was the problem
vm.$http.get('api/'+cid)
.then(function (res) {
if (res.data.status == "OK") {
vm.my_obj = res.data.body;
} else {
vm.setStatusMessage(res.data.body);
}
})
.catch(function (error) {
console.log(error);
vm.setStatusMessage("Error: "+error);
});
}
The solution was indicated in the third note here quoted below :
Note: If the destination is the same as the current route and only
params are changing (e.g. going from one profile to another /users/1
-> /users/2), you will have to use beforeRouteUpdate to react to changes (e.g. fetching the user information).
I had to do the following in my component:
Change the line let cid = vm.$route.params.id; in created() to let cid = vm.course.id
and, add the following to the component:
beforeRouteUpdate(to, from, next) {
if (to.params.id) {
this.my_obj.id = to.params.id;
}
// Some other code specific to my app
next();
}
I hope this helps someone stuck with the similar issue.
If you want to send a parameter with a query parameter you can use that syntax like that
this.$router.push({
path: this.localePath(`/bookings/${requestReservation?.attributes?.booking_id}`),
query: { requestReservation: requestReservation }
})
You can access it on the next page like that
this.$route.query.requestReservation
If you want send it fro nuxt-link than its syntax like that
<nuxt-link
:to="{ path: '/bookings/'+ requestReservation.attributes.booking_id,
query: { requestReservation } }">
Booking
</nuxt-link>
You can access it on the next page same like previous
this.$route.query.requestReservation