Whether I do this
Vue.router.push({ path: '/beats/catalog/1' })
or this
Vue.router.push({ name: 'BeatsCatalog', params: { page: 1 } })
I get the same result:
[vue-router] missing param for named route "BeatsCatalog": Expected "page" to be defined.
Router:
{
path: '/beats',
components: {
navbar: Navbar,
default: { template: `<router-view/>` }
},
children: [{
name: 'BeatsCatalog',
path: 'catalog/:page',
components: {
default: () => import('#/views/BeatsCatalog')
},
props: { default: true }
},
{
path: 'upload',
name: 'BeatsUpload',
components: {
default: () => import('#/views/BeatsUpload')
}
},
],
meta: { requiresAuth: true }
}
What's causing the issue? I see nothing wrong with my setup, I'm doing everything like in the documentation.
Thanks.
#Giacoma,
In your data property on the component BeatsCatalog the page is undefined when initally loaded. Hence you get the error.
So to solve this wrap your router-link in v-if.
Reference for the same error with better explaination is here:
https://github.com/vuejs/vue-router/issues/986
Related
I'm working with vue router 4, I've got an error when I'm passing post id to post details page via router props, it
runtime-core.esm-bundler.js:38 [Vue warn]: Invalid prop: type check failed for prop "destinationId". Expected Number with value 1, got String with value "1"
Now my questions is how can I pass the id as Integer? it's passing as String.
Here is my router file:
routes: [
{
path: '/',
name: 'HomeRoute',
component: HomeView
},
{
path: '/details/:slug/',
name: 'DestinationDetails',
component: () => import('../views/DestinationDetails.vue'),
props: route => ({...route.params , slug: route.params.slug}),
children: [
{
path: ':exprienceSlug',
name: 'experience.show',
component: () => import('../views/PlaceDetails.vue'),
props: route => ({...route.params,}),
},
]
},
{
path: '/:pathMatch(.*)*',
name: "NotFound",
component: () => import('../views/NotFound.vue'),
}
]
And Here is my Post file where form I'm passing the params via router-link tag
<router-link class="col-md-3"
v-for="experience in destination.experiences"
:key="experience.id"
:to="{name: 'experience.show', params: {exprienceSlug: experience.slug, destinationId: destination.id}}">
<PlacesCard :places="experience"/>
</router-link>
And this is post single page where I'm catching the id and fetch the posts.
props: {
destinationId: {
type: Number,
required: true,
default: 0,
},
exprienceSlug: {
type: String,
required: true,
},
},
computed: {
destination(){
return storeData.destinations.find(
destination => destination.id == this.destinationId
)
},
experience(){
return this.destination.experiences.find(
experience => experience.slug == this.exprienceSlug
)
}
},
route.params are of type string | string[].
But you can change that by parsing the params:
children: [
{
path: ':exprienceSlug',
name: 'experience.show',
component: () => import('../views/PlaceDetails.vue'),
props: ({ params }: Route) => ({
...route.params,
destinationId: Number(params.destinationId)
}),
},
]
I feel like I'm missing something very obvious but I can't figure it out. Please help!
I have the following routes defined:
const routes = [
{
path: '/',
name: 'Login',
component: () => import('../views/Login.vue'),
meta: {
authRedirect: true
}
},
{
path: '/companies',
name: 'Companies',
component: () => import('../views/Companies.vue'),
meta: {
requiresAuth: true
}
},
{
path: '/companies/:id',
name: 'Company',
component: () => import('../views/Company.vue'),
meta: {
requiresAuth: true
}
},
{
path: '*',
name: '404',
component: () => import('../views/404.vue')
}
]
Then I have the following in my component:
export default {
name: 'Company',
data() {
return {
company: {}
}
},
methods: {
getCompanyDetails: function() {
let self = this
axios.get('/api/companies/' + this.$route.params.id).then(function(response) {
self.company = response.data
}).catch(function() {
self.$router.push('companies')
})
}
},
created() {
this.getCompanyDetails()
}
}
Essentially everything is working if the API returns data, but inside the catch function I'm trying to push the route back to /companies. But it's redirecting to /companies/companies. How do I redirect it to the correct route?
Did you tried $router.push('/companies') (with a / in the path) ?
Also, you can use $router.push({ name: 'Companies' }) if you want to make it more clear, it will match the name defined in your routes.
My application have navbar with back button. The navbarTop is a named views, so I can have different navbar for each route, and the navbar needs props backRoute.
I define the back route like this:
{
path: '/:id',
name: 'orders detail',
components: {
default: OrderDetail,
navbarTop: Navbar,
},
props: {
navbarTop: {
backRoute: { name: 'orders' },
title: 'Order Detail',
},
default: true,
},
},
{
path: '/:id/request-cancel',
name: 'orders request cancel',
components: {
default: OrderRequestCancel,
navbarTop: Navbar,
},
props: {
navbarTop: {
backRoute: { name: 'orders', params: {id: ???} }, // how to get the id here?
title: 'Request Cancel',
},
default: true,
},
},
Is it possible to get the id in route and pass it as prop to the component?
The NavbarTop is named view and is used in many routes, so I can't update the back route from OrderRequestCancel component.
We can use Function Mode
props: {
navbarTop: route => ({
backRoute: { name: 'order detail', params: { id: route.params.id } },
title: 'Request Cancel',
}),
default: true,
},
Thank you #Yom S. for the hint.
I'm trying to set the class nav-active to the correct nav element, based from what url you're directly accessing the webapp for the first time.
I have a few routes:
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: () => import('./views/Home.vue')
},
{
path: '/account',
name: 'account',
component: () => import('./views/Account.vue')
}
]
});
And this is my navigation bar component (NavBar):
export default {
name: 'NavBar',
components: {
NavLogo,
NavItem
},
data() {
return {
navItems: [
{ /* root navigation */
id: 0,
type: 'root',
name: 'home',
route: '/',
active: this.$route.name === 'home' },
{
id: 1,
type: 'root',
name: 'account',
route: '/account',
active: false
}
}
}
}
The state of the active boolean inside navItems determines whether the navigation element should have the nav-active class. I'm trying to use the current route to determine whether active should be true or false, by using it this way:
active: this.$route.name === 'account'
But once for example I enter this dashboard directly from: http://localhost:8000/account
this.$route's items are all empty and the path is always /
Help is much appreciated,
Thanks
You are not tracking this.$route.name changes by default with this approach.
Try creating a computed property that resolves to this.$route.name, and use this in your data property declaration. In fact, you can just stick the whole thing in a computed property, since you're unlikely to change this.
export default {
name: 'NavBar',
components: {
NavLogo,
NavItem
},
computed: {
routeName(){
return this.$route.name
},
navItems(){
return [
{ /* root navigation */
id: 0,
type: 'root',
name: 'home',
route: '/',
active: this.routeName === 'home' },
{
id: 1,
type: 'root',
name: 'account',
route: '/account',
active: false
}
]
}
}
}
I have the following routes in my VueJS app:
const routes = [
{
path: '/',
component: PlacesList
},
{
name: 'place',
path: '/places/:name',
component: CurrentWeather,
children: [
{
name: 'alerts',
path: 'alerts',
component: ForecastAlerts
},
{
name: 'forecast',
path: 'forecast',
component: ForecastTimeline
}
]
}
];
ForecastTimeline receives props passed from CurrentWeather:
export default {
name: 'ForecastTimeline',
props: ['forecastData'],
components: {
ForecastDay
}
}
When I navigate to /places/:name/forecast from /places/:name everything works well. However, when I try to reach /places/:name/forecast directly I get a Cannot read property 'summary' of undefined error. This occurs because forecastData is fetched asynchronously within the CurrentWeather component. What is the proper way to handle asynchronous properties passed to a nested route?
Have you tried not displaying the subroutes components while fetching the data ?
Something like :
export default {
name: 'CurrentWeather',
data(){
return {
loading: true
}
},
created(){
this.fetchForecastData().then(() => {
this.loading = false;
});
},
methods: {
fetchForecastData() {
return fetch('http://..');
}
}
}
In CurrentWeather template :
<router-view v-if="!loading"></router-view>