vue.js accessing this.$route.params in mounted functions - vue.js

I'm trying to filter table of movies by director ID. The structure of a movie is:
{
id: 1,
title: "They All Lie",
releaseYear: 1989,
director: {
id: 18,
firstName: "Darci",
lastName: "Overill",
nationality: "China",
birthdate: "07/13/1973",
},
},
I want to filter the table using the $route.params.id. I have the following code:
<script>
import axios from "axios";
export default {
data: function () {
return {
directorId: this.$route.params.id,
director: {},
movies: [],
};
},
mounted: function () {
this.getDirector();
this.getMovies();
},
methods: {
getMovies: function () {
let url = "http://localhost:8080/movies/movies";
axios.get(url).then((response) => {
this.movies = response.data;
});
},
getDirector: function () {
let url = "http://localhost:8080/movies/directors/" + this.directorId;
axios.get(url).then((response) => {
this.director = response.data;
});
},
},
computed: {
filteredMovies: function () {
var v = this.$route.params.id;
alert(v);
return this.movies.filter(movie => movie.director.id === v);
},
}
};
</script>
I'm trying to access this.$route.params.id in the filteredMovies function. It works in the .alert function but I can't get the return this.movies.filter(movie => movie.director.id === v); to work. The filtering doesn't work. Any ideas please?

If you want a more elegant solution for parsing the router param id check tis out:
index.js(router file)
{
path: '/directors/:id',
name: 'Directors',
component: myComponentName,
props: (route) => {
const id = Number.parseInt(route.params.id);
return { id }
}
}
Component.vue
props: {
id: {
required: true,
type: Number,
}
With the above implementation you can remove the parsing in the component and also instead of doing this:
this.$route.params.id;
Now you can do:
this.id
And you have the parsed id with best practises ;)
Cheers

Related

How do you prepopulate a Vue text field from Vuex state?

I am trying to get a user's name to be prepopulated in the below text field.
<v-text-field
v-model.trim="name"
>{{ currentName }}</v-text-field>
data: () => ({
name: '',
}),
computed: {
currentName() {
return this.$store.state.name
},
}
I feel like I am missing something very simple, but I have tried so many variations that I am completely stumped. Please and Thanks for your help!
#Terry you got it! Thanks!
<v-text-field
v-model.trim="getName">{{ getName }}</v-text-field>
data: () => ({ name: '' })
computed: {
getName: {
get: function() {
return this.$store.state.name
},
set: function(newValue) {
this.name = newValue
}
}
methods: {
submit() {
if(!this.name) {
this.name = this.$store.state.name
}
this.$store.dispatch('updateMe', {
name: this.name,
});
}
export default new Vuex.Store({
state: {
name: null,
}

Vuejs - Undefined when calling method function

Used below VUE component JS to call "deleteuserParticulars" function inside ajax success. But, getting "deleteuserParticulars" is not defined.
Not sure which one I missed out on this and make this call. Can help to solve this issue soon pls? Thanks
import Vue from 'vue';
const userComponent = Vue.component('user-form-component', {
template: componentHTML(),
props: ['saveddata'],
components: {
userParticularsModalComponent
},
data: function () {
return {
userDetails: []
}
},
methods: {
deleteuser: function (newUser) {
let deleteDraftEndpointUrl = $('.main-component').attr('data-delete');
$.ajax({
url: deleteDraftEndpointUrl + newUser['draftId'],
type: 'GET',
success: function(s) {
if(s.status == 'success'){
this.deleteuserParticulars();
}
},
error: function(){
console.log('Error on delete user', error);
}
});
},
deleteuserParticulars: function(){
this.userDetails = this.userDetails.filter((user) => (user['info'].PP !== newuser['info'].PP);
this.userAllDetails = this.userDetails;
this.$emit('user', this.userDetails);
}
},
mounted: function () {
},
updated: function () {
console.log('U', this.waitForUpdate);
}
});
export default userComponent;
You need to use fat arrow function to get rid of this scope. Try out this snippet
import Vue from 'vue';
const userComponent = Vue.component('user-form-component', {
template: componentHTML(),
props: ['saveddata'],
components: {
userParticularsModalComponent
},
data: function () {
return {
userDetails: []
}
},
methods: {
deleteuser: function (newUser) {
let deleteDraftEndpointUrl = $('.main-component').attr('data-delete');
$.ajax({
url: deleteDraftEndpointUrl + newUser['draftId'],
type: 'GET',
success: (s) => { // the fix is here
if(s.status == 'success'){
this.deleteuserParticulars();
}
},
error: function(){
console.log('Error on delete user', error);
}
});
},
deleteuserParticulars: function(){
this.userDetails = this.userDetails.filter((user) => (user['info'].PP !== newuser['info'].PP);
this.userAllDetails = this.userDetails;
this.$emit('user', this.userDetails);
}
},
mounted: function () {
},
updated: function () {
console.log('U', this.waitForUpdate);
}
});
export default userComponent;
For more information: https://stackoverflow.com/a/34361380/10362396

How can I make the vue-router change when changing parameters? (vuex)

I'm making an app that has advanced search api.
You can choose what to look for and how to sort the results. The problem is that the page (vue-router) is updated only when the request changes, but it also should be updated when you change the search terms
How i can do this? I don't even have any ideas.
There is my code that is responsible for requesting the API and updating the router when the request is updated
export default {
name: "Search",
data: function () {
return {
selectedTag: 'story',
selectedBy: '',
};
},
components: {
'Item': Item
},
mounted() {
this.items = this.getItems(this.id)
},
beforeRouteUpdate(to, from, next) {
this.items = this.getItems(to.params.id);
next();
},
methods: {
getItems(id) {
this.items = this.$store.dispatch('FETCH_SEARCH_RESULTS', {id, tag: this.selectedTag, by: this.selectedBy});
return this.items;
},
},
created: function () {
this.getItems(this.$route.params.id);
},
computed: {
items: {
get() {
return this.$store.state.searchResults;
},
set(value) {
this.$store.commit("APPEND_SEARCH_RESULTS", value);
}
}
}
}

Nuxt asyncData result is undefined if using global mixin head() method

I'm would like to get titles for my pages dynamically in Nuxt.js in one place.
For that I've created a plugin, which creates global mixin which requests title from server for every page. I'm using asyncData for that and put the response into storage, because SSR is important here.
To show the title on the page I'm using Nuxt head() method and store getter, but it always returns undefined.
If I place this getter on every page it works well, but I would like to define it only once in the plugin.
Is that a Nuxt bug or I'm doing something wrong?
Here's the plugin I wrote:
import Vue from 'vue'
import { mapGetters } from "vuex";
Vue.mixin({
async asyncData({ context, route, store, error }) {
const meta = await store.dispatch('pageMeta/setMetaFromServer', { path: route.path })
return {
pageMetaTitle: meta
}
},
...mapGetters('pageMeta', ['getTitle']),
head() {
return {
title: this.getTitle, // undefined
// title: this.pageMetaTitle - still undefined
};
},
})
I would like to set title in plugin correctly, now it's undefined
Update:
Kinda solved it by using getter and head() in global layout:
computed: {
...mapGetters('pageMeta', ['getTitle']),
}
head() {
return {
title: this.getTitle,
};
},
But still is there an option to use it only in the plugin?
Update 2
Here's the code of setMetaFromServer action
import SeoPagesConnector from '../../connectors/seoPages/v1/seoPagesConnector';
const routesMeta = [
{
path: '/private/kredity',
dynamic: true,
data: {
title: 'TEST 1',
}
},
{
path: '/private/kreditnye-karty',
dynamic: false,
data: {
title: 'TEST'
}
}
];
const initialState = () => ({
title: 'Юником 24',
description: '',
h1: '',
h2: '',
h3: '',
h4: '',
h5: '',
h6: '',
content: '',
meta_robots_content: '',
og_description: '',
og_image: '',
og_title: '',
url: '',
url_canonical: '',
});
export default {
state: initialState,
namespaced: true,
getters: {
getTitle: state => state.title,
getDescription: state => state.description,
getH1: state => state.h1,
},
mutations: {
SET_META_FIELDS(state, { data }) {
if (data) {
Object.entries(data).forEach(([key, value]) => {
state[key] = value;
})
}
},
},
actions: {
async setMetaFromServer(info, { path }) {
const routeMeta = routesMeta.find(route => route.path === path);
let dynamicMeta;
if (routeMeta) {
if (!routeMeta.dynamic) {
info.commit('SET_META_FIELDS', routeMeta);
} else {
try {
dynamicMeta = await new SeoPagesConnector(this.$axios).getSeoPage({ path })
info.commit('SET_META_FIELDS', dynamicMeta);
return dynamicMeta && dynamicMeta.data;
} catch (e) {
info.commit('SET_META_FIELDS', routeMeta);
return routeMeta && routeMeta.data;
}
}
} else {
info.commit('SET_META_FIELDS', { data: initialState() });
return { data: initialState() };
}
return false;
},
}
}

returning article by id -- vue router, vuex

I am trying to return article ID and go the detail page for that id. I did something like below. But in the end it's not working... in the console there is an error popping up and pointing that:
api/v1/article[object%20Object]:1 Failed to load resource: the server
responded with a status of 404 (Not Found)
I need some help because I am a bit lost here... What I am missing here? what I do wrong?
Vuex
export const articles = {
state: {
article: {},
},
mutations: {
setArticle(state, article){
state.article = article;
},
},
getters: {
loadArticle(state){
return state.article;
},
},
actions: {
getArticle(id){
axios.get("api/v1/article" + id)
.then(response => {
this.commit('setArticles', response.data);
})
.catch(error => {
console.log(error);
})
},
}
}
Routes
{
path: "detail/:id",
name: "detail",
component: Vue.component("Detail", require("./pages/Detail.vue").default),
meta: {
requiresAuth: true
}
},
Article Component
export default {
components: {
maps,
},
data(){
return {
};
},
created(){
this.$store.dispatch( 'getArticle', {
id: this.$route.params.id
});
},
computed: {
article(){
return this.$store.getters.loadArticle;
}
}
}
Link to the article id
<router-link :to="{ name: 'detail', params: { id: item.id } }">詳細を見る</router-link>
Update
First parameter to store action is the store properties itself. This is the reason you get the store object. You need to receive id or any payload as second parameter.
actions: {
getArticle({ commit }, id){
axios.get("api/v1/article" + id)
.then(response => {
commit('setArticles', response.data);
})
.catch(error => {
console.log(error);
})
},
}
Here you see this
created(){
this.$store.dispatch( 'getArticle', {
id: this.$route.params.id
});
},
You are passing an object as parameter-
{
id: this.$route.params.id
}
You should be doing this instead -
created(){
this.$store.dispatch( 'getArticle', this.$route.params.id);
},