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
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')
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.
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.
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
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