vue-router returns 'function%20%' in url instead of param - vuejs2

So I'm showing some bread-crumbs like so..
<router-link to="/" class="breadcrumb-item">Home</router-link>
<router-link :to="{name: 'provider-dashboard', params: { id: provider_id }}" class="breadcrumb-item">Provider Dashboard</router-link>
<router-link :to="{name: 'provider-account-dash', params: { provider_id: provider_id, id: account_id }}" class="breadcrumb-item">Account Dashboard</router-link>
<router-link :to="{name: 'resident-profile', params: { account_id: account_id, id: resident_id }}" class="breadcrumb-item">Resident Profile</router-link>
I'm setting the param values with computed props that look like so..
account_id: {
get() {
return this.$store.getters['AssessmentPlanForm/getAccountId'];
},
set(value) {
this.$store.dispatch('AssessmentPlanForm/setAccountId', value);
},
},
provider_id: {
get() {
return this.$store.getters['AssessmentPlanForm/getProviderId'];
},
set(value) {
this.$store.dispatch('AssessmentPlanForm/setProviderId', value);
}
},
resident_id: {
get() {
return this.$store.getters['AssessmentPlanForm/getResidentId'];
},
set(value) {
this.$store.dispatch('AssessmentPlanForm/setResidentId', value);
},
},
I have confirmed that the values of the computed properties are correct, however when I click the router-link breadcrumb to go to desired location, the url shows users/function%20Number() instead of say users/18.
Why is this occurring and how can I get vue-router to properly render the parameter set by computed-prop?
Update from 1st comment
Here are the getters & no I'm not doing that for these attributes.
getId: (state) => {
return state.id;
},
getProviderId: (state) => {
return state.provider_id;
},
getEmployeeId: (state) => {
return state.employee_id;
},
getAccountId: (state) => {
return state.account_id;
},
getResidentId: (state) => {
return state.resident_id;
},
getSlug: (state) => {
return state.slug;
},
Update from 2nd comment
Vue.use(Router);
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [{
path: "/",
name: "home",
component: Splash,
prop: true
},
{
path: "/about",
name: "about",
component: About,
prop: true,
},
{
path: "/contact",
name: "contact",
component: ContactUs,
prop: true,
},
{
path: "/pricing",
name: "pricing",
component: Pricing,
prop: true,
},
{
path: "/faq",
name: "faq",
component: Faq,
prop: true
},
{
path: "/polls",
name: "polls",
component: Polls,
prop: true
},
{
path: "/login",
name: "login",
component: Login,
prop: true
},
{
path: "/provider-signup",
name: "provider-signup",
component: ProviderSignup,
prop: true
},
{
path: "/provider-dashboard/:id",
name: "provider-dashboard",
component: ProviderDash,
prop: true
},
{
path: "/providers/:id/edit",
name: "edit-provider",
component: EditProvider,
prop: true
},
{
path: "/provider/:id/employee-invitation",
name: "employee-invitation",
component: ProviderEmployeeInvite,
prop: true
},
{
path: "/employee-signup",
name: "employee-signup",
component: EmployeeSignup,
prop: true
},
{
path: "/employee-dashboard/:id",
name: "employee-dashboard",
component: EmployeeDash,
prop: true
},
{
path: "/employees/:id/edit",
name: "edit-employee",
component: EditEmployee,
prop: true
},
{
path: "/provider/:provider_id/employees",
name: "employees",
component: Employees,
prop: true
},
{
path: "/provider/:provider_id/accounts/new",
name: "provider-account-signup",
component: ProviderAccountSignup,
prop: true
},
{
path: "/providers/:provider_id/accounts/:id",
name: "provider-account-dash",
component: ProviderAccountDash,
prop: true
},
{
path: "/providers/:provider_id/accounts/:account_id/edit",
name: "edit-provider-account",
component: EditProviderAccount,
prop: true
},
.
.
.
]
});

So the answer was to fix a User error on my part. I forgot to assign the values of those attributes in a page I was working on.
The answer was to load the values of these attributes #created
retrieve(context, record_id) {
let resident_id = router.currentRoute.params.resident_id;
Axios.get(`/residents/${resident_id}/assessment_plan_forms/${record_id}`, {
headers: {
'Authorization': 'Bearer ' + window.$cookies.get('access_token'),
'x-amz-acl': 'public-read'
}
})
.then((response) => {
// let current_user = response.data.locals.current_user;
let provider = response.data.locals.provider;
let resident = response.data.locals.resident;
let account = response.data.locals.account;
let pdf_url = response.data.locals.pdf_url;
let date_of_record = response.data.locals.date_of_record;
let assessment_plan_form = response.data.locals.assessment_plan_form;
context.dispatch('AssessmentPlanForm/setId', assessment_plan_form.id, {
root: true
})
context.dispatch('AssessmentPlanForm/setProviderId', provider.id, {
root: true
})
context.dispatch('AssessmentPlanForm/setAccountId', account.id, {
root: true
})
context.dispatch('AssessmentPlanForm/setResidentId', resident.id, {
root: true
});
context.dispatch('AssessmentPlanForm/setPdfUrl', pdf_url, {
root: true
});
context.dispatch('AssessmentPlanForm/setDateOfRecord', date_of_record, {
root: true
});
context.dispatch('AssessmentPlanForm/setResidentSignature', resident.full_name, {
root: true
});
// redirect to show page
router.push({
name: 'show-assessment-plan',
params: {
resident_id: resident.id,
id: record_id
}
})
})
.catch((error) => {
console.log(error);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
And #retrieve gets called in the Created hook like:
methods: {
loadAssessmentPlan() {
this.$store.dispatch('AssessmentPlanForm/retrieve', this.$route.params.id)
},
},
created() {
this.loadAssessmentPlan();
},

Related

How to make routing differently than is now vuejs routing

I have a problem. I made routing what according how many addresses have user it will display them in manner 'Addresses(addrescount)'. global variable for getting address count is '$auth.user.address_count'
Task was if user have addresses show their count in sidebar if user do not have addresses show nothing .I did that but is any chance to have another solution to this problem
Is any chance to make it different then it now is?
how it looks like in programm
see line before {{route.display}}
<template>
<div class="col-lg-3">
<div class="profile-sidebar">
<ul class="list-unstyled">
<li v-for="route in nodes" :key="route.name">
<router-link :to="route.fullPath">
<template v-if="route.display === route.meta.title && $auth.user.address_count>0">
{{ route.display }}({{$auth.user.address_count}})
</template>
<template v-else>
{{ route.display }}
</template>
</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
import { routes } from '#/routes/routes';
export default {
data() {
return {
nodes: [],
}
},
async created() {
if (!this.$auth.user)
await this.$auth.updateUserInfo();
this.loadProfileNodes();
},
methods: {
loadProfileNodes() {
let node = routes.filter(route => route.path === '/profile').pop();
let hasLocalAccount = this.$auth.hasLocalAccount;
this.nodes = [];
node.children.forEach((route) => {
route['fullPath'] = node.path + '/' + route.path;
if ((!hasLocalAccount && route.path !== 'change-password') || (hasLocalAccount && route.path !== 'set-password')) {
this.nodes.push(route);
}
});
}
},
}
</script>
my routes.js see /profile children address-list route.
const routeOptions = [
{ path: '/', name: 'default', view: 'home', display: 'Home', meta: { showInMenu: true } },
{ path: '/401-forbidden', name: 'forbidden', view: 'errors/401-forbidden', display: '401 Forbidden' },
{ path: '/404-not-found', name: 'not-found', view: 'errors/404-not-found', display: '404 Page Not Found' },
{ path: '/login', name: 'login', view: 'auth/login' },
{ path: '/register', name: 'register', view: 'auth/register' },
{ path: '/auth/forgot-password', view: 'auth/forgot-password' },
{ path: '/auth/reset-password', view: 'auth/reset-password', props: (route) => ({ code: route.query.code }) },
{ path: '/auth/confirm-email', view: 'auth/confirm-email', props: (route) => ({ userId: route.query.userId, token: route.query.token }) },
{ path: '/admin/user-list', view: 'admin/users/user-list', display: 'Users', meta: { showInMenu: true, auth: { roles: 'Admin' } } },
{ path: '/admin/company-list', view: 'admin/companies/company-list', display: 'Companies', meta: { showInMenu: true, auth: { roles: 'Admin' } } },
{
path: '/profile',
view: 'profile/profile',
display: 'Edit profile',
meta: { auth: true },
children: [
{
path: '',
display: 'My Profile',
view: 'profile/edit-profile',
meta: { auth: true }
},
{
path: 'manage-logins',
display: 'External Logins',
view: 'profile/manage-logins',
meta: { auth: true }
},
{
path: 'address-list',
display: 'Addresses',
view: 'profile/addresses/address-list',
meta: { auth: true, title: 'Addresses' }
},
{
path: 'change-password',
display: 'Change Password',
view: 'profile/change-password',
meta: { auth: true }
},
{
path: 'set-password',
display: 'Set Password',
view: 'profile/set-password',
meta: { auth: true }
}
]
},
{ path: '*', redirect: { name: 'not-found' } }
];
function addDynamicImport(route) {
if (!route.view)
return route;
if (route.children && route.children.length) {
route.children = route.children.map(child => {
return addDynamicImport(child);
});
}
return {
...route,
component: () => import(/* webpackChunkName: "[request]" */ `#/components/views/${route.view}`)
}
}
const routes = routeOptions.map(route => {
return addDynamicImport(route);
})
export { routes }
router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import { routes } from './routes';
Vue.use(VueRouter);
let router = new VueRouter({
mode: 'history',
routes
});
export default router;
Answer is simple. You can add flag into '/profile/addres-list' route meta tag and check it if it is true/ True means we found the needed page
{
path: 'address-list',
display: 'Addresses',
view: 'profile/addresses/address-list',
meta: { auth: true, title: 'Addresses' }
},
into this (difference in the last line)
{
path: 'address-list',
display: 'Addresses',
view: 'profile/addresses/address-list',
meta: { auth: true, isAddressList: true }
}
and change
<template v-if="route.display === route.meta.title &&$auth.user.address_count>0">
to this
<template v-if="route.meta.isAddressList && $auth.user.address_count>0">

vuejs router-link props send data

I want to send data from home component via book.vue router link, but I am getting an error. Where am I doing wrong?
Home.vue
export default {
data() {
return {
data: {
attributes: {
name: 'Jonh',
age: '25',
},
},
}
},
}
router/index.js:
const routes = [
{ path: '/Library/:id', name: 'Book', component: Book, props: true },
]
navigation:
:to="{ name: 'Book', params: { id: book.id}, props: { data: data.attributes} }"
Book.vue
export default {
props: {
id: {
type: Array,
required: true
}
}
}

Push route to parent component inside a function (Vue)

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.

How to get the route params and pass it as props for named views?

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.

Redirect from beforeEnter causes infitite cycle and does not redirect

I have a problem with the nonworking redirect. I check is the user is logged in and the info is right, but when it comes to redirecting it does not redirect and just goes in this beforeEnter over and over again. Can somebody say what am I doing wrong?
I am presenting here my RouteConfig and the problem with the first beforeEnter.
export const routes: RouteConfig[] = [
{ path: '*', redirect: '/' },
{
path: '/',
component: router_view,
async beforeEnter(to, from, next) {
var hasPermission = await storage.get('state').user.tokens.access;
console.log(!!hasPermission)
if (!!hasPermission && from.fullPath.startsWith('/')) {
return next('profile');
} else {
return next()
}
},
children: [
{
name: 'landing',
meta: { requiresAuth: false },
path: '',
component: require('pages/index').default
},
{
meta: { requiresAuth: true },
path: 'seller',
component: require('pages/seller').default,
children: [
{
path: '',
name: 'profile',
redirect: 'profile'
},
{
path: 'account',
component: require('pages/seller/account').default
},
{
path: 'help/:url?',
component: require('pages/seller/help').default
},
{
path: 'profile',
component: require('pages/seller/profile').default
},
{
path: 'finances/:shop?',
name: 'finances',
props: route => ({
...route.query,
...route.params
}),
component: require('pages/seller/finances').default
},
{
path: 'shop',
component: require('pages/seller/shop').default,
children: [
{
path: '',
redirect: 'main'
},
{
path: 'main',
component: require('pages/seller/shop/main').default
},
// {
// path: 'rating',
// component: require('pages/seller/shop/rating').default
// },
{
path: 'design',
component: require('pages/seller/shop/design').default
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' },
component: require('pages/seller/invoices/index').default,
children: [
{
path: 'send',
name: 'invoices-send',
component: require('pages/seller/invoices/send').default,
},
{
path: 'return',
name: 'invoices-return',
component: require('pages/seller/invoices/return').default
},
{
path: 'create-send',
component: require('pages/seller/invoices/createInvoice').default,
},
{
path: 'create-return',
component: require('pages/seller/invoices/createInvoice').default,
},
]
},
{
path: 'products',
component: router_view,
children: [
{
path: '',
redirect: 'all'
},
{
path: 'new',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
component: require('pages/seller/products/new/createproduct').default
},
]
},
{
path: 'id/:productid/edit',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
name: 'edit-product',
props: route => ({ ...route.params, ...route.query }),
component: require('pages/seller/products/new/createproduct').default
},
{
path: 'sku',
name: 'edit-product-sku',
component: require('pages/seller/products/new/createsku').default,
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' }
},
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page-solo',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels-solo',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
{
path: 'stickers',
name: 'products-stickers',
component: require('pages/seller/products/stickers').default,
},
{
path: ':table',
name: 'product-list',
component: require('pages/seller/products/index').default,
props: _ => ({
tabletype: _.params.table
}),
beforeEnter(to, from, next) {
if (to.params.table === 'invoices') {
return next({ name: 'invoices' });
} else {
next();
}
},
children: [
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
]
}
]
}
]
},
{
meta: { requiresAuth: false },
name: 'signin',
path: '/signin',
component: router_view,
children: [
{
path: '',
name: 'signin',
component: require('pages/signin/index').default
},
{
path: 'restore',
component: router_view,
children: [
{
path: '',
component: require('pages/signin/restore/index').default
},
{
path: 'password',
component: require('pages/signin/restore/newpassword').default,
beforeEnter(to, from, next) {
if (from.fullPath.startsWith('/confirm'))
return next();
else
return next('/');
}
}
]
}
]
},
{
path: 'confirm',
meta: { requiresAuth: false },
component: require('pages/confirm/index').default,
beforeEnter(to, from, next) {
const path = from.fullPath ? from.fullPath : from.path;
if (path === '/signin' || path === '/signup' || path === '/signin/' || path === '/signup/' || path === '/' || path === '/signin/restore' || path === '/signin/restore/'
|| (from.path.startsWith('/confirm') && from.query === to.query)
|| to.query.from === 'account'|| to.query.from === 'restore')
return next();
else
return next('/');
}
},
{
name: 'signup',
path: 'signup',
meta: { requiresAuth: false },
component: router_view,
children: [
{
path: '',
name: 'signup',
component: require('pages/signup/index').default
},
{
path: 'social',
component: require('pages/signup/social').default
},
]
},
{
meta: { requiresAuth: false },
path: 'terms-of-use',
component: require('pages/terms-of-use').default
}
]
}
];