Using socket.io with aurelia - socket.io

I am trying to use socket.io in the framework aurelia. But when I start my server I get
error /Users/pierrehedkvist/TDDD272017/picasso/node_modules/socket.io-client/dist/socket.io.min.js
I am adding socket.io to my aurelia.json file like this:
"dependencies": [
....
{
"name": "socket.io-client",
"path": "../node_modules/socket.io-client/dist/socket.io.min"
}
]
And I use it like this (app.js). I try to import socket.io-client and test if I can write to the server.
import {inject} from 'aurelia-framework';
import {ApplicationState} from './application-state';
import io from 'socket.io-client';
var socket = io.connect( 'http://localhost:3000' );
io.emit('chat message', "TESTING");
#inject(ApplicationState)
export class App {
constructor (appState) {
this.appState = appState;
console.log(this.appState);
//this.appState.test = "Billy";
this.players = "";
}
/*activate() {
socket.on('chat message', function(msg){
io.emit('chat message', "TESTING");
console.log('message: ' + msg);
});
}*/
configureRouter(config, router) {
config.title = 'Piccasso or Not';
config.map([
{ route: '', moduleId: 'home', nav:true, name: "Home", title: 'Home'},
{ route: 'game', name: 'game',
moduleId: 'control/game', nav: true, title:'Create a game' },
{ route: 'draw', name: 'draw',
moduleId: 'control/draw', nav: true, title:'Draw something' },
{ route: 'theme', name: 'theme',
moduleId: 'theme', nav: true, title:'Theme' },
{ route: 'next-player', name: 'next-player',
moduleId: 'control/next-player', nav: true, title:'Next player' },
{ route: 'guess', name: 'guess',
moduleId: 'control/guess', nav:true, title: 'Guess'}
]);
this.router = router;
}
activate() {
this.message = 'Hellow world';
}
joinGame() {
console.log("Join lobby " + this.lobbyID)
}
createGame() {
console.log("createGame")
}
}
EDIT:
So I found out my path was incorrect, it now is this.
"name": "socket.io-client",
"path": "../node_modules/socket.io-client/socket.io.min"
Then in app.js I put:
import io from 'socket.io-client';
var socket = io.connect( 'http://localhost:3000' );
//io.emit('chat message', "TESTING");
and made a function called test() which is called from a button which successfully sends a message to my server.
test() {
socket.emit('chat message', "testing");
}

Related

How to redirect another router in Vue3 ? (used next.router in Laravel 8 with vue3)

It does not redirect after successfully logged in.
getting a console error TypeError: Cannot read property 'push' of undefine
Here my code.
I'm creating SPA in vue3 with Laravel 8.
import { ref } from "vue";
import { useRoute } from "vue-router";
export default {
setup() {
const form = ref(
{
email: "hudson.vilma#example.net",
password: "password",
isLoading: false,
},
);
const user = ref("");
function login() {
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/login', this.form).then(response => {
this.$router.push('/dashboard')
// useRoute.push('/dashboard');
// this.$router.push({ name: "Dashboard" });
}).catch(error => console.log(error)); // credentials didn't match
});
}
return { form, login, user , useRoute};
},
};
</script>
in app.js instant of vue &
require('./bootstrap');
import { createApp } from "vue";
import App from "./view/App.vue";
import router from "./router";
const app = createApp(App);
app.use(router);
app.mount("#app");
Try to use useRouter instead of useRoute and instantiate it like const router =useRouter() in setup function:
import { ref } from "vue";
import { useRouter } from "vue-router";
export default {
setup() {
const router =useRouter()
const form = ref(
{
email: "hudson.vilma#example.net",
password: "password",
isLoading: false,
},
);
const user = ref("");
function login() {
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/login', this.form).then(response => {
router.push('/dashboard')
}).catch(error => console.log(error)); // credentials didn't match
});
}
return { form, login, user ,};
},
};
</script>
Note that this couldn't be used in composition API.
You are using this.$router.push('/dashboard') in setup(). This cannot be used in setup(). Instead you can use...
router.push('/dashboard')

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'fire' of undefined"

I'm creating a laravel SPA and I'm using vue.js as a framework. I'm adding a sweetalert package in my project but whenever i use the toast function it gets me an error. I tried using other functions like swal.fire and it works except for toast.fire. Can someone help me with this? Here are some of my codes.
app.js
require('./bootstrap');
import Vue from 'vue'
import { Form, HasError, AlertError } from 'vform'
import moment from 'moment'
import VueRouter from 'vue-router'
import VueProgressBar from 'vue-progressbar'
import swal from 'sweetalert2'
window.Form = Form;
window.swal = swal;
window.toast = toast;
window.Vue = require('vue');
Vue.use(VueRouter)
Vue.component(HasError.name, HasError)
Vue.component(AlertError.name, AlertError)
const toast = swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000
});
Vue.use(VueProgressBar, {
color: 'rgb(143, 255, 199)',
failedColor: 'red',
height: '2px'
})
const routes = [
{ path: '/dashboard', component: require('./components/Dashboard.vue').default },
{ path: '/profile', component: require('./components/Profile.vue').default},
{ path: '/users', component: require('./components/Users.vue').default}
]
const router = new VueRouter({
mode: 'history',
routes // short for `routes: routes`
})
Vue.filter('upText', function(text){
return text.charAt(0).toUpperCase() + text.slice(1);
});
Vue.filter('myDate', function(created){
return moment(created).format('MMMM Do YYYY');
});
Vue.component('dashboard', require('./components/Dashboard.vue').default);
Vue.component('profile', require('./components/Profile.vue').default);
Vue.component('users', require('./components/Users.vue').default);
const app = new Vue({
el: '#app',
router
});
Users.vue
<template>
//html codes
</template>
<script>
export default {
data(){
return{
users: {},
form: new Form({
name: '',
email: '',
password: '',
type: '',
bio: '',
photo: '',
})
}
},
methods: {
loadUsers(){
axios.get("api/user").then(( {data }) => (this.users = data.data));
},
createUser(){
this.$Progress.start();
this.form.post('api/user');
toast.fire({
type: 'success',
title: 'User Created',
position: 'top-end',
})
this.$Progress.finish();
}
},
created() {
console.log('Component mounted.');
this.loadUsers();
}
}
</script>
At the point this line runs, toast will be undefined:
window.toast = toast;
Note that the line const toast = swal.mixin({ comes later. You would need to write these lines the other way around.
Personally I wouldn't expose these directly on window in the first place. Either import them as required or add them to the Vue prototype:
Vue.prototype.$toast = toast
You'd then use it by calling this.$toast.fire in your components.
You have to call toast.fire in then event of axios.post as below,
createUser(){
this.$Progress.start();
axios.post('api/user', this.form).then(response => {
toast.fire({
type: 'success',
title: 'User Created',
position: 'top-end',
})
this.$Progress.finish();
}).catch(error => {
this.$Progress.finish();
});
You can handle success and failure and show toast messages .then and .catch event respectively.
Hope this helps.

Unable to fetch data from API (Resource blocked by client) in Vuex

I'm trying to fetch some data from my API using vuex + axios, but the action give me a "Network Error" (ERR_BLOCKED_BY_CLIENT).
when i was using json-server it works fine, but it doesn't work with my API even with 'Allow-Access-Control-Origin': '*'
actions
const actions = {
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
},
setGlobalParams({ commit }, obj) {
commit('clearParams')
commit('setParams', obj)
}
}
component
<script>
/* Vuex import */
import { mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Assuming your cors issue was properly resolved the reason you cannot access the data is that it is being set before the axios promise is being resolved.
Change:
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
}
to:
async fetchSearch({ commit, state }) {
await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
commit('clearProducts')
commit('setProducts', response.data)
}).catch(err) {
console.log(err)
}
}
Further you should use mapState. Assuming setProducts is setting a state object like products this would look like:
<script>
/* Vuex import */
import { mapState, mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
computed: {
mapState([
'products'
])
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Now you can refrence this.products in JS or products in your template.

Angular 2 unit test for component

I am using ng2 with webpack 2.
I cant figure out how to test component functions
Here is my component
import { Component, OnInit } from '#angular/core';
import { GlobalDataService } from '../global.service';
import { Router } from '#angular/router';
#Component({
selector: 'login',
templateUrl: './login.component.html'
})
export class LoginComponent {
constructor(private gd: GlobalDataService, private router: Router) { }
login(): void {
this.gd.shareObj['role'] = 'admin';
this.router.navigateByUrl('/login');
}
}
I would like to test login() function and see, if this.gd.shareObj['role'] = 'admin'; is truly set as admin.
What could .spec.ts file look like?
I would do it as follows:
class RouterStub {
navigateByUrl(url: String) { return url; }
}
class GlobalDataServiceStub {
shareObj: any = {};
}
describe('LoginComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [
{ provide: GlobalDataService, useClass: GlobalDataServiceStub },
{ provide: Router, useClass: RouterStub }
]
});
fixture = TestBed.createComponent(LoginComponent);
comp = fixture.componentInstance;
});
it('should set role to admin',
inject([GlobalDataService], (gd: GlobalDataService) => {
comp.login();
expect(gd.shareObj['role']).toBe('admin');
})
);
});
Plunker Example

Send data to components in VueJS + Vue Router

I can't pass data from app to compenent. After render it shows only clear html, without data from vue. All works, but without data((
My code from app.js:
var Series = Vue.component('Series', require('./components/Series.vue'),{
props: {
series: {
type: Array,
default: []
},
images: {
type: Array,
default: []
},
showPhotos: {
type: Boolean,
default: false
}
}
});
const Bar = { template: '<div>bar</div>' }
const Foo = { template: '<div>foo</div>' }
const routes = [
{ path: '/weedings', component: Series },
{ path: '/', component: Foo },
{ path: '/family', component: Foo },
{ path: '/other', component: Foo },
{ path: '/videos', component: Bar },
{ path: '/blog', component: Bar },
{ path: '/about', component: Foo },
{ path: '/contacts', component: Bar }
]
const router = new VueRouter({
routes // short for routes: routes
});
var app = new Vue({
el: "#app",
router,
data: {
series: [],
currentSerie: 0,
images: [],
showPhotos: false
},
methods: {
fetchSeries: function(){
this.$http.get('/api/fetchSeries').then((response) => {
this.series = response.body
}, (response) => {
alert("fail")
});
},
fetchPhotos: function(id){
this.showPhotos = false;
this.$http.get('/api/fetchPhotos/'+id).then((response) => {
this.images = response.body
this.showPhotos = true;
$("html, body").animate({ scrollTop: 60 }, "500");
}, (response) => {
alert("fail")
});
},
photos: function(id){
this.fetchPhotos(id)
}
},
created: function(){
this.fetchSeries()
setTimeout(function(){ require('./custom'); }, 1000);
}
});
When I dont use vue-router, all works fine. And i know i can pass data to components in this way: <my-component :artribute="value"></my-component>, but in this case IDK how to pass data.
Use function mode like this:
{
path: '/weedings',
component: Series,
props: () => (
{ series: app.series, images: app.images, showPhotos: app.showPhotos }
)
}
Check working example in JSFiddle.
Note: You have to use vuex as a centralized store for all the components in an application to be able to implement more complex scenarios.
In your routes declaration you should add props
`const routes = [
{ path: '/weedings', component: Series, props: true}]`
Here mentioned: Passing props to Vue.js components instantiated by Vue-router

Resources