call function inside data() property - javascript

I'm trying to fetching some data for my search tree and i'm not able to get the data directly from axios or to call a function because it can't find this.
export default {
name: 'SideNavMenu',
data () {
return {
searchValue: '',
treeData: this.getData(),
treeOptions: {
fetchData(node) {
this.onNodeSelected(node)
}
},
}
},
In the data() I have treeOptions where I want to call a function called onNodeSelected. The error message is:
"TypeError: this.onNodeSelected is not a function"
can anybody help?

When using this, you try to call on a member for the current object.
In JavaScript, using the {} is actually creating a new object of its own and therefore, either the object needs to implement onNodeSelected or you need to call a different function that will allow you to call it on an object that implements the function.
export default {
name: 'SideNavMenu',
data () {
return {
searchValue: '',
treeData: this.getData(), // <--- This
treeOptions: {
fetchData(node) {
this.onNodeSelected(node) // <--- and this
}
},
}
},
//are calling functions in this object :
{
searchValue: '',
treeData: this.getData(),
treeOptions: {
fetchData(node) {
this.onNodeSelected(node)
}
},
//instead of the object you probably are thinking
I would avoid creating object blocks within object blocks like those as the code quickly becomes unreadable and rather create functions within a single object when needed.
I am guessing you would have the same error message if you tried to get a value from treeData as well

You are not calling the function, or returning anything from it. Perhaps you're trying to do this?
export default {
name: 'SideNavMenu',
data () {
return {
searchValue: '',
treeData: this.getData(),
treeOptions: fetchData(node) {
return this.onNodeSelected(node)
},
}
},
Regardless, it is not considered good practice to put functions inside data properties.
Try declaring your variables with empty values first, then setting them when you get the data inside beforeCreate, created, or mounted hooks, like so:
export default {
name: 'SideNavMenu',
data () {
return {
searchValue: '',
treeData: [],
treeOptions: {},
}
},
methods: {
getData(){
// get data here
},
fetchData(node){
this.onNodeSelected(node).then(options => this.treeOptions = options)
}
},
mounted(){
this.getData().then(data => this.treeData = data)
}
},
Or if you're using async await:
export default {
name: 'SideNavMenu',
data () {
return {
searchValue: '',
treeData: [],
treeOptions: {},
}
},
methods: {
getData(){
// get data here
},
async fetchData(node){
this.treeOptions = await this.onNodeSelected(node)
}
},
async mounted(){
this.treeData = await this.getData()
}
},

Related

Cannot read property 'substring' of undefined NUXT

I am having problems in an html tag that uses an object from my object in store.
When i refresh my page, the array from my sotre is empty, so i when i refresh in the index page, it will first load the html, then the mounted method, and its where i fill my store. its says that Cannot read property 'substring' of undefined
index.vue that i use this object:
<p v-html="pegaPrimeiroPost.conteudo.substring(0,500)"></p>
export default of index.vue:
computed: {
...mapGetters({
postsDB: "postagensDB/pegaPosts",
pegaPrimeiroPost: "postagensDB/pegaPrimeiroPost",
}),
},
methods: {
...mapActions({
buscaPostDB: "postagensDB/pegaPostsDB",
}),
},
async mounted() {
**await this.buscaPostDB();**
});
},
this object pegaPrimeiroPost is an objetct from my array that i fill from my database.
store/postagensDB:
import axios from 'axios'
export const state = () => ({
posts: [],
primeiroPost: {},
})
export const getters = {
pegaPosts(state) {
return state.posts;
},
pegaPrimeiroPost(state) {
return state.primeiroPost;
},
}
export const actions = {
async pegaPostsDB(state) {
await axios
.get("http:/MY_API_ADRESS")
.then((response) => {
state.commit('carregaStatePosts', response.data)
})
.catch((response) => {
console.log(response)
});
},
}
export const mutations = {
async carregaStatePosts(state, postsDB) {
state.posts = postsDB.posts;
state.primeiroPost = state.posts[0];
},
}
If i erase the substring() method, reload the page, then it will fill my store; and then re-add the substring(), it works, but wont solve my prob. Can anyone help me?
I've never used Vue, but this sounds like you have some sort of async action that populates the object, but your default value (used before the async call has completed) doesn't have that property. The quickest solution is probably just give it a value if it doesn't exist:
(pegaPrimeiroPost.conteudo || '').substring(0,500)
or set a "default" object with that property:
export const state = () => ({
posts: [],
primeiroPost: { conteudo: '' },
})

How can i use my component method in my vue?

I have a method "aggiornaQuantity" in this component that i would use in my vue. How can i do?
Obviously I did various tests without any success
Vue.component('todo-item', {
props: ['todo'],
template: '...',
methods:
{
aggiornaQuantity: function()
{
return this.todo.quantity = this.value ;
}
}
var app7 = new Vue
(
{
el: '#app-7',
data:
{
message: '${Message}',
risultato: true,
groceryList: [],
product: '',
selected: '',
},
methods:
{
.....
}
Edit: I'm not sure if you want to know how to use the function or why your function doesn't work (as commented above). If it's the former, here's the answer:
You have to call it in one of the lifecycle instances. Most of the time, we call it in mounted().
...
methods: {
foo () {
// do something
},
},
mounted() {
this.foo();
},
...

How to use data from one hook to other hook in Vue.js?

In my vue.js application I send request by axios package in created() hook. I add response to array called coordinates. I want to use that array outside of created() hook. For example in mounted() hook or in functions which we can set in methods.
Right now when I tried to use self.coordinates outside created() hook it return undefined. When I use this.coordinates it return just [__ob__: Observer].
Whats wrong I did?
export default {
name: "Map",
data() {
return {
coordinates: [],
}
},
created() {
let self = this;
axios.get('URL').then(function (response) {
let coordinates = [];
for (let i = 0; i < response.data.length; i++) {
coordinates.push([response.data[i]["LATITUDE"], response.data[i]["LONGITUDE"]]);
}
self.coordinates = coordinates;
});
},
mounted() {
console.log(self.coordinates); // undefined
consol.log(this.coordinates); // [__ob__: Observer]
},
}
I would prefer "mounted" and move the logic into methods for reusability. The method can be kicked from anywhere afterwards. In the example below, I prefered kicking the method direcly. Watchers is another option.
Here is the fiddle https://jsfiddle.net/dj79ux5t/2/
new Vue({
el: '#app',
data() {
return {
coordinates: []
}
},
mounted() {
let self = this;
axios.get('https://api.weather.gov/').then(function (response) {
self.coordinates = response.data;
self.greet();
});
},
methods: {
greet: function () {
console.warn(this.coordinates.status);
}
}
})
I think instead of mounted , you should use watch . You call some link so it will take time to load that data , watch method will trigger when your data is updated ...
watch: {
coordinates: {
handler: function (updateVal, oldVal) {
console.log(updateVal)
},
deep: true
}
},

Access to props in data

can you tell me what I do wrong? I need access to props in my data object in component.
I have defined component like this:
export default {
components: {...},
computed: {...},
props: {
userCode: {
type: String,
default: null
}
},
data: () => ({
options: {
callback: function() {
console.log(this.userCode) // prints undefined
return ...;
}
}
}),
methods: {...},
...,
}
prop value I define in router like this:
{
path: '/user/bbb',
name: 'users',
component: userView,
meta: {
requiresLoggedIn: true,
},
props: {userCode: 'XXX'}
}
When I tried in same component render this prop in html like this {{this.userCode}} so it's worked and display my passed code. How to access to prop in options data object? Thanks.
Vue.js best practices aside the reason this.userCode is undefined is because in that case the callback function defines its own this and the global this is not being used. To use the global this either use
callback: () => {}
or
callback: function() {
console.log(this.userCode) // prints undefined
return ...;
}.bind(this)
you can read more about the arrow function here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

How can I access this.$route from within vue-apollo?

I'm constructing a GraphQL query using vue-apollo and graphql-tag.
If I hardcode the ID I want, it works, but I'd like to pass the current route ID to Vue Apollo as a variable.
Does work (hardcoded ID):
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: 'my-long-id-example'
}
}
}
However, I'm unable to do this:
Doesn't work (trying to access this.$route for the ID):
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: this.$route.params.id
}
}
}
I get the error:
Uncaught TypeError: Cannot read property 'params' of undefined
Is there any way to do this?
EDIT: Full script block to make it easier to see what's going on:
<script>
import gql from 'graphql-tag'
const PropertyQuery = gql`
query Property($id: ID!) {
Property(id: $id) {
id
slug
title
description
price
area
available
image
createdAt
user {
id
firstName
lastName
}
}
}
`
export default {
name: 'Property',
data () {
return {
title: 'Property',
property: {}
}
},
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: this.$route.params.id // Error here!
}
}
}
}
</script>
You can't have access to "this" object like that:
variables: {
id: this.$route.params.id // Error here!
}
But you can like this:
variables () {
return {
id: this.$route.params.id // Works here!
}
}
Readimg the documentation( see Reactive parameters section) of vue-apollo you can use vue reactive properties by using this.propertyName. So just initialize the route params to a data property as then use it in you apollo object like this
export default {
name: 'Property',
data () {
return {
title: 'Property',
property: {},
routeParam: this.$route.params.id
}
},
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
// Reactive parameters
variables() {
return{
id: this.routeParam
}
}
}
}
}
While the accepted answer is correct for the poster's example, it's more complex than necessary if you're using simple queries.
In this case, this is not the component instance, so you can't access this.$route
apollo: {
Property: gql`{object(id: ${this.$route.params.id}){prop1, prop2}}`
}
However, you can simply replace it with a function, and it will work as you might expect.
apollo: {
Property () {
return gql`{object(id: ${this.$route.params.id}){prop1, prop2}}`
}
}
No need for setting extra props.

Categories

Resources