vuejs router-link props send data - vue.js

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

Related

Vue I18n multi language

I'm doing multi-language support with vue js, everything works fine, but when I change the language, the data in the data
menuItem name does not change.
Vuei18n
<template v-slot:MenuItem>
<MenuItems v-for="(Item,Index) in menuItem"
:key="Index"
:items="Item"
:depth="Index"
>
<router-link :to="Item.path">{{Item.name}}</router-link>
</MenuItems>
</template>
export default {
name: "Nav",
data() {
return {
menuItem: [
{
name: this.$t('navbar.home'),
path: '',
},
{
name: this.$t('navbar.gallery'),
path: 'gallery',
},
{
name: this.$t('navbar.contact'),
path: 'contact',
},
],
}
}
}
data() is only called once when creating the component, and it's not intended to be reactive.
(So basically when your component is being created, it gets the your current translation as initial values)
To make a property reactive on $t(), you should use computed var instead:
export default {
name: "Nav",
data() {
// exclude from here
return {};
},
computed: {
menuItem() {
return [
{
name: this.$t("navbar.home"),
path: "",
},
{
name: this.$t("navbar.gallery"),
path: "gallery",
},
{
name: this.$t("navbar.contact"),
path: "contact",
},
];
},
},
};

Vue router-link pass prop getting undefined

This is how I passed the prop:
<router-link :to="{ name: 'Cart', params: { payment_method: 'cod' } }">
Router component is like this:
{
path: "/cart",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
in the receiving route, Props:
props: {
payment_method: String,
},
I am getting undefined as value for payment_method. what is wrong here?
Change your router component path to:
{
path: "/cart/:payment_method",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
Try to set payment_method as slug in route with props:true and catch the route's prop directly in data of vue instance
<router-link :to="{ name: 'Cart', params: { payment_method: 'cod' } }">
{
path: "/cart/:payment_method",
name: "Cart",
component: Cart,
props: true,
meta: {
requiresAuth: true,
},
},
catch directly in data
data: function () {
return {
payment_method: this.$route.params.payment_method,
};
},
This will resolve your problem

How to pass an object directly in a prop through Vue Router?

In Vue JS3, my Vue component, I can pass props like this: Parent:
<script>
export default {
data() {
return {
links: [],
};
},
methods: {
editLink(el) {
this.$router.push({
name: "EditLink",
params: {
id: el.id,
short_link: el.short_link,
long_link: el.long_link,
},
});
},
},
};
</script>
Component:
<script>
export default {
props: ["elem"],
data() {
return {
link: {},
};
},
mounted() {
this.link = {
id: this.$route.params.id,
short_link: this.$route.params.short_link,
long_link: this.$route.params.long_link,
};
},
};
</script>
But If I pass the Object named el directly like this:
this.$router.push({
name: "EditLink",
params: {
elem: el,
},
});
When I try to print it out, I get the value of elem as [Object Object], instead of an actual object. Why is this happening? What's the solution?
Try out to spread the el instead of assigning each value to the respective key :
this.$router.push({
name: "EditLink",
params: {...el},
});
then in the target page :
mounted() {
this.link = {...this.$route.params};
},

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

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();
},

Angular 5 Parent reloads when Child route changes

I am having a problem where my parent component (LoggedInComponent) is getting reloaded every time one of the child components changes (child route change).
I have searched high and low for an answer but can't seem to find anything suitable to my situation.
Here is my app-routing.module.ts
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: '', component: LoggedInComponent, canActivateChild: [AuthGuard], children: [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: DashboardComponent },
{ path: 'groups', component: GroupsComponent, data: { role: [PermissionEnum.Groups_View] } },
{ path: 'groups/edit/:id', component: GroupDetailComponent, data: { role: [PermissionEnum.Groups_Edit] } },
{ path: 'groups/create', component: GroupDetailComponent, data: { role: [PermissionEnum.Groups_Create] } },
{ path: 'users', component: UsersComponent, data: { role: [PermissionEnum.Users_View] } },
{ path: 'users/edit/:id', component: UserDetailComponent, data: { role: [PermissionEnum.Users_Edit] } },
{ path: 'users/create', component: UserDetailComponent, data: { role: [PermissionEnum.Users_Create] } },
{ path: 'profile', component: ProfileComponent },
{ path: 'profile/:tabindex', component: ProfileComponent },
{ path: 'settings', component: SettingComponent, data: { role: [PermissionEnum.Global_Settings_View] } },
{ path: 'external-login/:result', component: ExternalLoginProvidersComponent },
{ path: 'permissions/:id/:type', component: PermissionsComponent, data: { role: [PermissionEnum.Users_AssignPermissions] } },
{ path: 'permission-denied', component: PermissionDeniedComponent },
{ path: 'reference-data/:type', component: ReferenceDataComponent, data: { role: [PermissionEnum.Sms_Template_View] } },
{ path: 'reference-data/:type/edit/:id', component: ReferenceDataDetailsComponent, data: { role: [PermissionEnum.Sms_Template_Edit] } },
{ path: 'reference-data/:type/create', component: ReferenceDataDetailsComponent, data: { role: [PermissionEnum.Sms_Template_Create] } },
{ path: 'tenants', component: TenantsComponent, data: { role: [PermissionEnum.Tenant_View] } },
{ path: 'tenants/edit/:id', component: TenantDetailComponent, data: { role: [PermissionEnum.Tenant_Edit] } },
{ path: 'tenants/create', component: TenantDetailComponent, data: { role: [PermissionEnum.Tenant_Create] } },
{ path: 'sms-campaigns', component: SmsCampaignsComponent, data: { role: [PermissionEnum.SmsCampaign_View] } },
{ path: 'sms-campaigns/create', component: CreateSmsCampaignComponent, data: { role: [PermissionEnum.SmsCampaign_Create] } },
{ path: 'sms-campaigns/details/:id', component: SmsCampaignDetailsComponent, data: { role: [PermissionEnum.SmsCampaign_View] } },
{ path: 'document-library', component: LibraryDocumentsComponent },
{ path: 'report-management', component: ReportManagementComponent },
{ path: 'report-management/create', component: CreateReportComponent },
{ path: 'report-management/:id', component: IdpComponent },
{ path: 'report-management/edit/:id', component: ReportDetailsComponent },
{ path: 'report/:reportName', component: ReportComponent }
]
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
I have the main router-outlet in my app.component.html which after loggin in takes you to the LoggedInComponenet which has the header, footer, left menu and another router-outlet for the children.
This is my LoggedIn.componenent.html
<app-header></app-header>
<div class="m-grid__item m-grid__item--fluid m-grid m-grid--ver-desktop m-grid--desktop m-body">
<app-left-menu></app-left-menu>
<div *ngIf="loading">
<app-loading-indicator></app-loading-indicator>
</div>
<div class="center-display" *ngIf="childrenLoadingAllowed">
<router-outlet class="m-grid__item m-grid__item--fluid m-wrapper" [ngClass]="{ hidden: loading }"></router-outlet>
</div>
</div>
<app-footer></app-footer>
I then have my LoggedIn.component.ts
import { Component, OnInit } from '#angular/core';
import { BaseComponent } from '../shared/base.component';
#Component({
selector: 'app-logged-in',
templateUrl: './logged-in.component.html',
styleUrls: ['./logged-in.component.css']
})
export class LoggedInComponent extends BaseComponent implements OnInit {
public loading = true;
public childrenLoadingAllowed = false;
constructor() {
super();
}
ngOnInit() {
this.layoutService.setLoadingEvent
.subscribe((res: boolean) => {
if (this.loading !== res)
this.loading = res;
});
}
}
And then finally here is the left-menu which keeps reloading when i load a child
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { BaseComponent } from '../../shared/base.component';
import { PermissionEnum, LookupClient, LookupType, LookUpDto } from '../../../services/web-api-generated';
#Component({
selector: 'app-left-menu',
templateUrl: './left-menu.component.html',
styleUrls: ['./left-menu.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class LeftMenuComponent extends BaseComponent implements OnInit {
public hasReports = false;
public reports: Array<LookUpDto> = new Array<LookUpDto>();
constructor(private lookupClient: LookupClient) {
super();
this.loadReportMenuItems();
}
ngOnInit() {
this.layoutService.rebuildReportMenu
.subscribe(res => {
this.loadReportMenuItems();
});
}
private loadReportMenuItems(): void {
this.lookupClient.getLookUpValues(LookupType.MunicipalReports)
.subscribe((res: Array<LookUpDto>) => {
this.reports = res;
this.reports.forEach(element => {
element.value = element.value.replace(/\s+/g, '-').toLocaleLowerCase();
});
this.hasReports = res.length > 0;
});
}
}
I fixed the problem by moving the api call to a service with a variable there and only loading the data if its not already set or if the force variable is passed through.
I believe this is a bug as mentioned here: https://github.com/angular/angular/issues/18374
yes, canActivateChild reloads whole parent component while changing between child routes