Vuejs - Undefined when calling method function - vue.js

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

Related

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

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

Vue.js with Axios use data from other method

I have a external api which returns a json of a user with some attributes like username. I want to use this username in my vue methods as a url parameter and defined the function getUser(). My problem is that the parameter keeps undefined
Here is my code
<script>
import Axios from 'axios-observable'
export default {
data () {
return {
appointments: {},
event_counter: 0,
user: ''
},
methods: {
getUser: function () {
Axios
.get('http://127.0.0.1:5000/users/get_user')
.subscribe(response => { this.user = response.data.username })
},
getAppointments: function () {
Axios
.get('http://127.0.0.1:5000/appointments/get_appointments?user=' + this.user)
.subscribe(response => { this.appointments = response.data })
},
fetchData: function () {
setInterval(() => {
this.getAppointments()
}, 150000)
}
},
mounted () {
//this.user = this.getUser()
this.getUser()
this.fetchData()
},
created () {
//this.user = this.getUser()
this.getUser()
this.getAppointments()
}
}
</script>
I tried some variants with return response.data or data: this.getUser() etc. Obtaining the user in template with {{ user }} works fine but isn't helpful. I don't have any syntax or runtime error from vue/electron-vue
Any idea?
Finally got a solution!
<script>
import Axios from 'axios'
export default {
data () {
return {
appointments: {},
event_counter: 0,
user: 'test'
}
},
methods: {
getUser: function () {
return Axios
.get('http://127.0.0.1:5000/users/get_user')
.then(response => {
this.user = response.data.username
return this.user
})
},
getAppointments: function () {
this.getUser()
.then(data => {
let url = 'http://127.0.0.1:5000/appointments/get_appointments?user=' + data
Axios
.get(url)
.then(response => { this.appointments = response.data })
})
},
fetchData: function () {
setInterval(() => {
this.getAppointments()
}, 150000)
}
},
mounted () {
this.fetchData()
},
created () {
this.getAppointments()
}
}
</script>
The solution was to change the call of the getUser() and retrieve the date in the arrow function block .then(data =>).
The answer of #loan in this Issue give me the hint: How to set variable outside axios get.
Thanks a lot to all.
<script>
import Axios from 'axios-observable'
export default {
data () {
return {
appointments: {},
event_counter: 0,
user: ''
},
computed: {
updatedUrl: {
return `http://127.0.0.1:5000/appointments/get_appointments?user=${this.user}`
}
},
methods: {
forceGetUsername() {
return this.user
},
getUser: function () {
Axios
.get('http://127.0.0.1:5000/users/get_user')
.subscribe(response => { this.user = response.data.username })
},
getAppointments: function () {
console.log(updatedUrl)
Axios
.get(updatedUrl)
.subscribe(response => { this.appointments = response.data })
},
// Below can remain the same
}
</script>
So it seems the url is being cached and not updated once created. So I added new function to ensure the latest value is being returned. Not very ideal.
Added the URL to computed property. If this doesn't work then I am lost as well :(

How to set a value inside a variable on data() using a function?

I'm creating a Vue.js component inside a Laravel App.
After I catch the response with an axios request, I can't put a value inside a variable on method data()
Here is the code:
app.js
require('./bootstrap')
window.Vue = require('vue')
Vue.component('card', require('./components/card.vue'))
let app = new Vue({
el: '#app'
})
card.vue
<script>
module.exports = {
props: [
'name'
],
data: function() {
return {
projects: [],
}
},
mounted() {
this.getProjects() // NOT WORK?
},
methods: {
getProjects: function() {
axios.get('/api/v1/getProjects').then(function (response) {
console.log(response.data)
this.projects = response.data // NOT WORK
}).catch(function (error) {
console.log(error)
}).then(function () {
})
},
}
}
</script>
It's because of using this in response callback. You should use an arrow function (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) or save the context in separate variable.
Try to add .bind(this) or replace function with =>:
getProjects: function() {
axios.get('/api/v1/getProjects').then((response) => {
console.log(response.data)
this.projects = response.data // NOT WORK
}).catch((error) => {
console.log(error)
}).then(function () {
})
},

VueJS: Setting data initially based on http response

So I have a template .vue file:
<template>
<div id="app">
<textarea v-model="input" :value="input" #input="update"></textarea>
<div v-html="compiledMarkdown"></div>
</div>
</template>
<script>
var markdown = require('markdown').markdown;
export default {
name: 'app',
data() {
return {
input: '# Some default data'
}
},
mounted: function () {
this.$nextTick(function () {
this.$http.get(window.location.pathname + '/data').then((response) => {
this.input = response.body.markdown;
}) })
},
computed: {
compiledMarkdown: function() {
this.$http.post(window.location.pathname, {
"html": markdown.toHTML(this.input)}).then(function() {
},function() {
});
return markdown.toHTML(this.input);
}
},
methods: {
update: function(e) {
this.input = e.target.value
}
}
}
</script>
In the mounted function I am trying to set input equal to the response of an HTTP request, but when you view this file this.input is still the same as it was initially declared. How can I change this.input inside the compiledMarkdown function to be this.input in the mounted function. What other approaches might I take?
You can not call a async method from a computed property, you can use method or watcher to run asynchronous code, from docs
This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
You have to ran that relevant code when input changes, like following:
var app = new Vue({
el: '#app',
data: {
input: '# Some default data',
markdown : ''
},
methods: {
fetchSchoolData: function (schoolId) {
var url = this.buildApiUrl('/api/school-detail?schoolId=' + schoolId);
this.$http.get(url).then(response => {
this.schoolsListData = response.data;
}).catch(function (error) {
console.log(error);
});
},
},
mounted: function () {
this.$nextTick(function () {
this.$http.get(window.location.pathname + '/data').then((response) => {
this.input = response.body.markdown;
})
})
},
watch: {
// whenever input changes, this function will run
input: function (newInput) {
this.$http.post(window.location.pathname, {
"html": markdown.toHTML(this.input)}).then(function() {
},function() {
this.markdown = markdown.toHTML(this.input);
});
}
},
Have a look at my similar answer here.

TypeError: this.$set is not a function

Hi I am geting this error:
Uncaught (in promise) TypeError: this.$set is not a function
And here is the code:
export default {
data: function() {
return { movies: '' }
},
ready: function() {
this.showMovies()
},
methods: {
showMovies: function() {
this.$http.get(config.api.url + '/movies').then(function (response) {
this.$set('movies', response.data)
})
}
}
}
The reason why this.$set is not a function in your example code is because this doesn't refer to Vue ViewModel instance anymore.
To make code you've posted working, you need to keep reference to it:
export default {
data: function() {
return { movies: '' }
},
ready: function() {
this.showMovies()
},
methods: {
showMovies: function() {
var vm = this; // Keep reference to viewmodel object
this.$http.get(config.api.url + '/movies').then(function (response) {
vm.$set('movies', response.data)
})
}
}
}
in the callback function you're loosing the Vue instance (this), this could be solved by using the arrow function ()=>{...} :
this.$http.get(config.api.url + '/movies').then((response)=> {
this.$set('movies', response.data)
})
or binding the callback to this :
this.$http.get(config.api.url + '/movies').then(function (response) {
this.$set('movies', response.data)
}).bind(this)