Vue: Push to array on event - events

I have two separate Vue components that need to talk to each other via an eventbus. Like:
form-component.Vue
import events from './events'
export default {
...
methods() {
sumbitForm() {
events.$emit('form-submitted', data)
}
}
...
}
other-component.Vue
import events from './events'
export default {
....
mounted() {
events.$on('form-submitted, data => {
this.list.push(data);
}
},
data() {
return {
list: []
}
}
....
}
But when the event is listened to 'this' is not referring to 'other-component' but to the actual eventbus 'events'.
How would I go about this problem?

It sounds to me like you're misreading the problem. An arrow function binds its context, and the context of that arrow function is correctly bound to the other-component because it is within a method, and methods are auto-bound to their components. The below example works as expected.
const events = new Vue();
Vue.component('formComponent', {
template: '<button #click="submitForm">Submit</button>',
methods: {
submitForm() {
events.$emit('form-submitted', {
foo: 1
});
}
}
});
Vue.component('otherComponent', {
template: '<div><div v-for="item in list">{{item}}</div></div>',
data() {
return {
list: []
}
},
mounted() {
events.$on('form-submitted', data => {
this.list.push(data);
});
}
});
new Vue({
el: '#app'
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<form-component></form-component>
<other-component></other-component>
</div>

One solution would be to copy your this in a variable outside and use that to access the component's data properties. For example, this should work:
import events from './events'
export default {
....
mounted() {
var that = this;
events.$on('form-submitted, function(data) {
that.list.push(data);
)
},
data() {
return {
list: []
}
}
....
}

Related

Cannot destructure property of {intermediate value} as it is undefined

I have just started using graphql for the first time as I have integrated my NEXTJS app with strapi. But I have received this error message Cannot destructure property 'data' of '(intermediate value)' as it is undefined.
I followed this tutorial - enter link description here
Just modified it to what I wanted. This is my graphql:
query {
posts {
data {
attributes {
heading
}
}
}
}
And this is my vs code:
export async function getStaticProps() {
const client = new ApolloClient({
url: 'http://localhost:1337/graphql/',
cache: new InMemoryCache(),
})
const { data } = await client.query({
query: gql`
query {
posts {
data {
attributes {
heading
}
}
}
}
`,
})
return {
props: {
posts: data.posts,
},
}
}
FULL CODE:
import { ApolloClient, InMemoryCache, gql } from '#apollo/client'
export default function Blog({ posts }) {
console.log('posts', posts)
return (
<div>
{posts.map(post => {
return (
<div>
<p>{posts.heading}</p>
</div>
)
})}
</div>
)
}
export async function getStaticProps() {
const client = new ApolloClient({
url: 'http://localhost:1337/graphql/',
cache: new InMemoryCache(),
})
const { data } = await client.query({
query: gql`
query {
posts {
data {
attributes {
heading
}
}
}
}
`,
})
return {
props: {
posts: data.posts,
},
}
}
I really don't know where to begin with this.
Firstly check whether or not you are receiving empty data from API.
If its array, check its length or use methods like Array.isArray(myArray).
If its object, make a function like this to check objects.
function isObjectEmpty(obj) {
return (
!!obj && // 👈 null and undefined check
Object.keys(obj).length === 0 &&
obj.constructor === Object
)
}
export default isObjectEmpty
if the data is empty return notFound prop as true to show your 404 page.
// This function gets called at build time
export async function getStaticProps({ params, preview = false }) {
// fetch posts
// check validity data
return isObjectEmpty(pageData)
? { notFound: true }
: {
props: {
posts
}
}
}
Secondly add a failsafe mechanism like the use of optional-chaining to securely access nested values/properties.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
export default function Blog({ posts }) {
console.log('posts', posts)
return (
<div>
{posts?.length && posts?.map(post => {
return (
<div>
<p>{posts?.heading}</p>
</div>
)
})}
</div>
)
}
I was running into the same error while testing using Jest.
It turns out I was mocking all of graphql, but I had to specifically mock the return value.

vue.js how to call multiple url data in single axios

i am trying get multiple url data in single axios. i already added single url but i want to add another url.
i tired this but it giving null object error
{{ BusinessCount }}
{{ UserCount }}
import axios from "axios";
export default {
data() {
return {
businesslists: [],
Userslist: [],
};
},
async asyncData({ $axios }) {
let { datas } = await $axios.$get("/Userslist");
return {
Userslist: datas,
};
},
computed: {
UserCount() {
return Object.keys(this.Userslist).length;
},
},
async asyncData({ $axios }) {
let { data } = await $axios.$get("/Businessregisterlist");
return {
businesslists: data,
};
},
computed: {
BusinessCount() {
return Object.keys(this.businesslists).length;
},
},
};
i want to show like this
<p>{{ BusinessCount }}</p>
<p>{{ UserCount }}</p>
1st url
/Businessregisterlist
2nd url
/Userlist
my code
<template>
<p>{{ BusinessCount }}</p>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
BusinessCounts: [],
};
},
async asyncData({ $axios }) {
let { datad } = await $axios.$get("/Businessregisterlist");
return {
BusinessCounts: datad,
};
},
computed: {
BusinessCount() {
return Object.keys(this.BusinessCounts).length;
},
},
};
</script>
In your tried code you define the asyncData function 2 times. That's incorrect. But you can make 2 calls to the server in a single asyncData function.
Try:
async asyncData({ $axios }) {
let { datad } = await $axios.$get("/Businessregisterlist");
let { dataUsers } = await $axios.$get("/Userslist");
return {
Businesslist: datad,
Userslist: dataUsers
};
},
computed: {
BusinessCount() {
return Object.keys(this.Businesslist).length;
},
UserCount() {
return Object.keys(this.Userslist).length;
},
},
Make sure you correctly define the Businesslist and Userslist in the data section.

Laravel + Vue.js - how to have a global variable?

I have a project using Laravel and Vue.js. I guess it wasn't the best idea not to separate them, but we learn from our mistakes ;)
Here is how it works:
I have been struggling trying to put global variables, such as "current user". Now, I am calling /currentuser through axios each time I need it, or I put it in props, but it drives my crazy... How can I make it global?
I am wondering if Vuex could work in my project, as everything is called from Laravel, the routes as well...
I have tried several things in app.js (here are 2 of them, mixed):
var curruser=null;
axios.get('/currmember').then(
response => {
curruser=response.data;
}
);
Vue.mixin({
methods: {
},
data: function() {
return {
myvaiable: '', //this doesn't work eather
get currentUser() {
if(curruser==null){
axios.get('/currmember').then(
response => {
curruser=response.data;
return curruser;
}
);
}
return curruser;
}
}
}
});}
in TestComponent.vue
<template>
<div>
{{currentUser}}
{{myvariable}} <!-- none of them display anything -->
</div>
</template>
Here is how things are working (simplify them very much):
app.js
import Vue from 'vue';
window.Vue = require('vue');
var App = Vue.component('app', require('./App.vue').default, {
name: 'app'
});
var shol = Vue.component('test', require('./components/TestComponent.vue').default);
let lang=localStorage.Lang!=null?localStorage.Lang:'fr';// = document.documentElement.lang.substr(0, 2);
init();
function init(){
const app = new Vue({
el: '#app',
i18n,
components:{test
}
});
var curruser=null;
axios.get('/currmember').then(
response => {
curruser=response.data;
}
);
Vue.mixin({
methods: {
},
data: function() {
return {
currentUser: 'blabla',
get currentUser2() {
if(curruser==null){
axios.get('/currmember').then(
response => {
curruser=response.data;
console.log(curruser);
return curruser;
}
);
}
return curruser;
}
}
}
});}
test.blade.php
#extends('template')
#section('pageTitle', 'test' )
#section('contenu')
<div >
<test></test>
</div>
#endsection
web.php
Route::get('/test', function () {
return view('test');
});
You may use vuex to access current authenticated user:
On app.js:
import Vue from 'vue';
import store from './store';
const app = new Vue({
el: '#app',
store,
i18n,
components:{ test },
created() {
store.dispatch('getUser');
}
});
The store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {},
},
getters: {
user: state => state.user,
},
mutations: {
setUser(state, user) {
state.user = user;
},
},
actions: {
getUser({ commit }) {
return new Promise((resolve, reject) => {
axios.get('/currmember')
.then(result => {
commit('setUser', result.data);
resolve();
})
.catch(error => {
reject(error.response && error.response.data.message || 'Error.');
});
});
},
}
})
The test component:
<template>
<div>
{{ currentUser }}
</div>
</template>
<script>
export default {
computed: {
currentUser() {
return this.$store.state.user;
}
}
};
</script>

vue.js Failed to mount component: template

i am working hard to solve this issue but not found any one please help me about this
here is my code
calling component
Vue.component('select2', require('./components/select2.vue'));
html of component
<template>
<select>
<slot></slot>
</select>
</template>
here is my vue.js script
<script>
export default {
props: ['options', 'value', 'params'],
mounted: function () {
var vm = this;
var params = !this.params ? {} : this.params;
params.val = this.value;
if(this.options) {
params.data = this.options;
}
$(this.$el).val(this.value);
$(this.$el).select2(params);
$(this.$el).on('change', function () {
vm.$emit('input', $(this).val())
})
$(this.$el).val(this.value).trigger('change');
},
watch: {
value: function (value) {
$(this.$el).val(value);
},
options: function (options) {
var params = !this.params ? {} : this.params;
if(this.options) {
params.data = this.options;
}
$(this.$el).select2(params);
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>
but still getting this error i tried alot of things but not working please help me i can give you more detials if you needed i am using laravel ,gulp etc

d3-drag - “Cannot read property 'button' of null”

I am using the neo4j-d3 charts in my application as follows. I did checkout the git repo of Neo4j-d3 and created seperate repo as 'neo4jd3'
import { Component } from 'react'
import { Redirect } from 'react-router-dom';
import Neo4jd3 from 'neo4jd3';
import * as d3 from 'd3';
class xxx extends Component {
constructor(props) {
super(props);
this.getAllValues = this.getAllValues.bind(this);
this.nodeRadius = 30
}
componentWillMount() {
this.getAllValues ();
}
createGraphObj(data) {
let nodeRadius = this.nodeRadius
let neo4jd3Obj = new Neo4jd3('#graphId', {
nodeLetters: {
'Test': (node) => {
return 'Check'
},
'Check': function (node) {
return 'Check'
}
},
nodeColors: {
'TestColor': 'rgba(250,204,163,1)',
'CheckColor': 'rgba(124,212,248,1)',
},
nodeOutlineColors: {
'TestColor': 'rgba(245,151,67,1)',
'CheckColor': 'rgba(18,147,212,1)',
},
infoPanel: false,
minCollision: nodeRadius,
neo4jData: data,
nodeRadius: nodeRadius,
nodeletterSize: 16,
onNodeClick: (node) => {
}
})
}
getAllValues () {
this.xxx.getAllValues().then(res => {
// console.log('----- getAllDomains -----', res)
let temp = {
"results": [{
"data": [{
"graph": res[0]
}]
}]
}
this.createGraphObj(temp);
})
}
render() {
return (
<div>
<div>
<div id="graphId"></div>
</div>
</div>
)
}
}
export default xxx
. Grpah wise all are fine, but at the time of dragging I am getting the following error
Cannot read property 'button' of null
from the following code
function defaultFilter() {
return !d3Selection.event.button;
}
I saw the following link
d3-drag 0.3.0 - "Cannot read property 'button' of null"
but no luck :(
Help me out for this one.
Thanks in advance

Resources