Integration of Socket.IO with VUE Framework - vue.js

Hello I am trying to implement socket.io with vue.js however I cannot access the emits in the different views.
After configuring main.js I can get emits on the APP, but I can't get them on HOME.
Is it possible to help with this situation.
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import vuetify from "./plugins/vuetify";
import * as io from "socket.io-client";
import VueSocketIO from "vue-socket.io";
Vue.use(
new VueSocketIO({
debug: true,
connection: io("http://localhost:3001"),
})
);
Vue.config.productionTip = false;
new Vue({
router,
store,
vuetify,
render: (h) => h(App),
}).$mount("#app");
Here I have the implementation of the first view, and here I have access to the socket.io emit!
<template>
<v-app id="inspire">
<v-app-bar app color="white" flat>
<v-container class="py-0 fill-height">
<v-avatar class="mr-10" color="grey darken-1" size="32"></v-avatar>
<v-btn v-for="link in links" :key="link" text>
{{ link }}
</v-btn>
<v-spacer></v-spacer>
<v-responsive max-width="260">
<v-switch
v-model="switchLogIn"
label="login"
color="success"
hide-details
></v-switch>
</v-responsive>
</v-container>
</v-app-bar>
<v-main class="grey lighten-3">
<v-container>
<v-row>
<v-col cols="2">
<v-sheet rounded="lg">
<v-list color="transparent">
<v-list-item v-for="n in 5" :key="n" link>
<v-list-item-content>
<v-list-item-title> List Item {{ n }} </v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="my-2"></v-divider>
<v-list-item link color="grey lighten-4">
<v-list-item-content>
<v-list-item-title to="/about">
{{ nextSip["Estado Processo"] }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-sheet>
</v-col>
<v-col>
<v-alert icon="mdi-database-outline" prominent text type="info">
FILA DE TRABALHO COM {{ workFlowSize }}.
</v-alert>
<v-sheet min-height="70vh" rounded="lg" v-if="switchLogIn">
<router-view></router-view>
</v-sheet>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
data: () => ({
links: ["Dashboard"],
switchLogIn: false,
workFlow: "",
workFlowSize: 0,
nextSip: Object,
}),
sockets: {
connect: function () {
this.$swal("Conectado com Sucesso", "Servidor Localhost:3001", "success");
console.log("socket connected");
},
workFlowSize(data) {
this.workFlowSize = data;
},
nextSip: (data) => {
console.log(data);
},
},
watch: {
switchLogIn: function (value) {
if (value == true) {
console.log("Im LOGIN");
}
},
},
};
</script>
but not here
<template>
<div class="home">
<SipForm/>
</div>
</template>
<script>
import SipForm from "#/components/SipForm.vue";
export default {
name: "Home",
components: {
SipForm,
},
data: () => ({
workFlowSize: 0,
}),
sockets: {
connect: function () {
this.$swal("Conectado com Sucesso", "Servidor Localhost:3001", "success");
console.log("socket connected");
},
workFlowSize(data) {
this.workFlowSize = data;
},
nextSip: (data) => {
console.log(data);
},
},
};
</script>

Related

After adding 1 item to TODO app fails when I just type on text field, How to fix it?

this might be stupitest question to ask but I just can't understand why this is happening , I am trying to Build simple TODO app with Nuxt Js with Vuex, When I add one Item it works fine and displays, after that if I just type something on text field app failds and gives error
"Error: [vuex] do not mutate vuex store state outside mutation handlers."
Here is index.vue file
<template>
<v-main>
<v-row justify="center" class="py-10">
<h1 class="teal--text">NUXT TODO APP</h1>
<v-col cols="12" md="10">
<v-text-field type="text" outlined v-model="item.text"> </v-text-field>
<v-btn color="teal" x-large class="mt-3" #click="addItem">Add</v-btn>
</v-col>
<v-col cols="8">
<h1 v-if="items.length <= 0">No Data Found</h1>
<v-list v-else>
<v-list-item v-for="item in items" :key="item.id" class="my-5">
<v-list-item-content>
<v-list-item-title>{{ item.text }}</v-list-item-title>
</v-list-item-content>
<v-list-item-action class="d-flex flex-row">
<v-btn color="teal"> Edit </v-btn>
<v-btn color="error" class="mx-5"> Delete </v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</v-col>
</v-row>
</v-main>
</template>
<script>
export default {
computed: {
items() {
return this.$store.state.items;
},
},
data: () => ({
item: {
text: "",
},
}),
methods: {
addItem() {
this.$store.commit("addItem", this.item);
},
},
};
</script>
And here is index.js file for Vuex
export const state = () => ({
items: [],
});
export const mutations = {
addItem(state, payload) {
state.items.push(payload);
},
};
please guide me what the hell I am missing here.
Thank You.

How can I solve the issue with redirection?

I am setting up a new project on nuxt and I've made one new layout for a login page, and created a page login.
In my default layout I am setting middleware: 'auth' and in my middleware I am checking for a token and if not authenticated I am redirecting the user to the login page.
The funny thing is that when I've just set it up it worked fine but after some time (I tried to go back with my code to find the issue) I started to receive an Error Redirected when going from "/" to "/login" via a navigation guard.
I don't have any redirects but the one in the auth middleware.
What can be a problem here that I cannot see?
// middleware/auth.js
export default ({ app, error, redirect }) => {
const hasToken = !!app.$apolloHelpers.getToken()
if (!hasToken) {
error({
errorCode: 503,
message: 'You are not allowed to see this'
})
return redirect('/login')
}
}
// layouts/default.vue
<template>
<v-app dark>
<v-navigation-drawer
v-model="drawer"
:mini-variant="miniVariant"
:clipped="clipped"
fixed
app
>
<v-list>
<v-list-item
v-for="(item, i) in items"
:key="i"
:to="item.to"
router
exact
>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title v-text="item.title" />
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar :clipped-left="clipped" fixed app>
<v-app-bar-nav-icon #click.stop="drawer = !drawer" />
<v-btn icon #click.stop="clipped = !clipped">
<v-icon>mdi-application</v-icon>
</v-btn>
<v-toolbar-title v-text="title" />
<v-spacer />
</v-app-bar>
<v-main>
<v-container>
<nuxt />
</v-container>
</v-main>
<v-footer :absolute="!fixed" app>
<span>© {{ new Date().getFullYear() }}</span>
</v-footer>
</v-app>
</template>
<script>
export default {
middleware: ['auth'],
data() {
return {
clipped: false,
drawer: true,
fixed: true,
items: [
{
icon: 'mdi-apps',
title: 'Welcome',
to: '/',
},
{
icon: 'mdi-account-group-outline',
title: 'Clients',
to: '/clients',
},
{
icon: 'mdi-briefcase-check-outline',
title: 'Orders',
to: '/orders',
},
{
icon: 'mdi-briefcase-clock-outline',
title: 'Pending Orders',
to: '/pending-orders',
},
],
miniVariant: false,
right: true,
rightDrawer: false,
title: 'Title',
}
},
}
</script>
// layouts/login.vue
<template>
<v-app dark>
<v-main>
<v-container>
<nuxt />
</v-container>
</v-main>
</v-app>
</template>
<script>
export default { }
</script>
// pages/login.vue
<template>
<div>test login</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
Sorry) apparently I removed layout property from the login page component

whoe to solve this proplem :updating a chiled component in vuejs update all the other childeren?

I want to update the likes for the specific comment
this is the parent component Commnet.vue
<template>
<v-list class="list" color="white" three-line>
<template v-for="cmnt in comments" class="mb-2">
<v-card color="transparent" class=" text-no-wrap" :key="cmnt._id">
<v-list-item class="item" :key="cmnt._id">
<v-list-item-avatar>
<v-img :src="cmnt.author.image"></v-img>
</v-list-item-avatar>
<v-list-item-content class="black--text">
<v-list-item-title>{{
cmnt.author.first_name + " " + cmnt.author.last_name
}}</v-list-item-title>
<v-list-item-subtitle class="black--text" v-html="cmnt.comment">
{{ cmnt.comment }}
</v-list-item-subtitle>
</v-list-item-content>
<v-card class="like-count">
<v-icon color="blue">mdi-thumb-up </v-icon>
<Likes :_id="cmnt._id"/>
</v-card>
</v-list-item>
</v-card>
<v-card
:key="cmnt._id"
outlined="true"
color="transparent"
class="ml-6"
>
</template>
and this is the child component inside comment component it has it is own state completely separated form the parent.
Like.vue
<template>
<div>
<v-card >
</v-card>
{{likes.length}}
</div>
</template>
<script>
import axios from "axios";
import io from "socket.io-client";
export default {
name:"Likes",
created:async function(){
axios.get(`comment/${this._id}`)
.then(results=>{
if (results.data){
this.likes =results.data;
}
})
.catch(err=> console.log(err));
let url = "";
if (process.env.NODE_ENV === "production") {
url = "/";
} else {
url = "http://localhost:5000";
}
this.socket = io(url);
this.socket.on("receive-like",async (data)=>{
console.log(data)
this.new_like= data;
console.log(this.new_like)
const el = this.likes.find(el => el._id === this.new_like._id)
if (el){
const index = this.likes.indexOf(el);
this.$forceUpdate()
return this.likes.splice(index,1)
}else{
this.likes.push(this.new_like);
console.log(this.likes)
this.$forceUpdate()
}
})
},
mounted:async function(){
},
props:{
_id:{
type: String
}
},
data:()=>({
user:{},
likes:[],
new_like:{}
}),
computed:{
},
}
</script>
so when clicking like the new like object get pushed to the array of likes for the concerned comment but likes for all comments get updated at ones.
in case somebody is wondering I just made adding the new like object conditional
if(data.comment._id === this._id)

Cannot execute method when v-btn clicked with Vuetify

I can't execute method when clicking v-btn.
my template
<template>
<v-app>
<v-main>
<v-card class="mx-auto" max-width="500" tile>
<v-text-field
label="Main input"
hide-details="auto"
v-model="newTodo"
></v-text-field>
<v-list disabled>
<v-subheader>TODOS</v-subheader>
<v-list-item-group v-model="todos" color="primary">
<v-list-item v-for="todo in todos" v-bind:key="todo.id">
<v-list-item-content>
<v-list-item-title v-text="todo.text"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-btn color="blue-grey" class="white--text" v-on:click="test">
<v-icon dark>mdi-delete</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-main>
</v-app>
</template>
my script
<script>
export default {
name: "app",
data: () => ({
todos: [],
newTodo: ""
}),
created() {
this.reload();
},
methods: {
reload() {
let vm = this;
const axios = require("axios").create({
baseURL: "http://localhost:5000",
headers: {
"Content-Type": "application/json"
},
responseType: "json"
});
axios
.get("/get_todos")
.then(function(response) {
// handle success
console.log(response);
vm.todos = response.data;
})
.catch(function(error) {
// handle error
console.log(error);
})
.finally(function() {
// always executed
});
},
test() {
console.log("test");
}
}
};
</script>
What I've tried
I replaced the "v-on:click" with "#click", "#onclick" and "#click.native" but failed to see "test" on the console.
Version of plugins
Vue: v2.6.12
Vuetify: v2.3.16
As Michal Levý said, I tried removing disabled from v-list. I succeeded to execute test method.

How to set Vuetify pagination on list

With vuetify, I am trying to set <v-pagination> on a <v-list-item> but I don't see how to bind my items (n in notification) to the pagination. Does it need an extra function? Most of the documentation I found was with vuetify tables.
<template>
<div>
<v-card
class="mx-auto"
max-width="300"
tile
>
<v-list rounded>
<v-subheader>NOTIFICATIONS</v-subheader>
<v-list-item-group color="primary">
<v-list-item
v-for="(n, i) in notification"
:key="i"
>
<v-list-item-content>
<v-list-item-title v-text="n.payload"></v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-pagination
v-if="pages > 1"
v-model="pagination.page"
:length="pages"
></v-pagination>
</v-list-item-group>
</v-list>
</v-card>
</div>
</template>
<script>
export default {
name: "status",
data() {
return {
pagination: {
page: 1,
total: 0,
perPage: 0,
visible: 3
},
notification: [],
}
},
computed: {
pages () {
Math.ceil(this.notification.length / 3)
}
}
}
</script>
How do I set the number of items displayed by page?
you can use the pagination component's v-model to get a list of items to display.
here's an example
<div id="app">
<v-app id="inspire">
<div class="text-center">
{{ visiblePages }}
<v-pagination
v-model="page"
:length="Math.ceil(pages.length/perPage)"
></v-pagination>
</div>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
page: 1,
perPage: 4,
pages: [0,1,2,3,4,5,6,7,8,9,10,11,12,13]
}
},
computed: {
visiblePages () {
return this.pages.slice((this.page - 1)* this.perPage, this.page* this.perPage)
}
}
})
https://codepen.io/scorch/pen/RwwGKrQ
you can then pass the visiblePages to you item list.