So, I am wanting to retrieve an updated list of contacts on once a new contact is added. Unfortunately, axios is only loading the get request on the 'beforeMount()' instance. When I try and call the function inside of an axios.post request when it's successful, the list of contacts is gone until I refresh the page again.
I'm running Laravel 5.7 and VueJs 2.5.22.
import axios from 'axios';
export default {
data() {
return {
companion: {
name: '',
desc: '',
primaryPhone: '',
secondaryPhone: '',
email: '',
address: '',
notes: '',
image: ''
},
characterAmount: 0
};
},
props: {
addCompanion: {
type: Boolean
}
},
methods: {
checkNotesLength(e) {
this.characterAmount =
document.getElementById('notes').value.length;
if (e.keyCode === 8) {
this.characterAmount--;
if (this.characterAmount < 0) {
this.characterAmount = 0;
}
} else {
this.characterAmount++;
if (this.characterAmount > 150) {
this.characterAmount = 150;
}
}
},
processFile(e) {
var input = e.target;
var reader = new FileReader();
reader.onload = (e) => {
this.companion.image = e.target.result;
}
reader.readAsDataURL(input.files[0]);
},
getCompanions() {
const url = window.location + 'companions';
axios.get(url)
.then((response) => {
this.companions = response.data;
})
.catch((error) => {
// handle error
console.log(error);
});
},
submitCompanion() {
const formData = {
name: this.companion.name,
desc: this.companion.desc,
primaryPhone: this.companion.primaryPhone,
secondaryPhone: this.companion.secondaryPhone,
email: this.companion.email,
address: this.companion.address,
notes: this.companion.notes,
image: this.companion.image
}
axios.post('/companion/create', formData)
.then(this.getCompanions())
.then((response) => {
this.addCompanion = !this.addCompanion;
//need to clear form and include messages, also need to add validation
})
.catch((error) => {
console.log(error);
});
}
}
}
The beforeMount() function is on my App.vue, which just calls the same getCompanions function as the above one you see.
The issue that I see in your code is that you are not passing the callback correctly. This code will execute the function getCompanions() immediately:
.then(this.getCompanions())
To pass it as a callback try something like this
.then(this.getCompanions.bind(this))
// OR
.then(() => this.getCompanions())
This is probably because your url structure is wrong.
const url = window.location + 'companions';
should be
const url = window.location + '/companions';
Related
So this is the scenario / premises:
In order to populate a chat queue in real time I need to open a connection to a websocket, send a message and then set the data to a websocket store. This store will basically manage all the websocket state.
Before populating the chat queue there's two parameters I need: a shiftId coming from one http API request and a connectionId coming from the websocket. Using those two parameters I finally can subscribe to a third http API and start receiving messages to populate the chat queue.
The problem is that due to the async behaviour of the websocket (or that's what I think, please feel to correct me if I'm wrong) I always get an empty "connectionId" when trying to make the put to that "subscription" API. I have tried with async/await and promises but nothing seems to work. I'm pretty new to async/await and websockets with Vuex so pretty sure I'm doing something wrong.
This is the user vuex module where I do all the login/token operations and dispatch a "updateEventsSubscription" action from the shift vuex module. In order for the "updateEventsSubscription" action to work I need to get the response from the "processWebsocket" action (to get the connectionId parameter) and from the "startShift" action (to get the shiftId parameter) coming from the shifts vuex module:
import UserService from '#/services/UserService.js'
import TokenService from '#/services/TokenService.js'
import router from '#/router'
export const namespaced = true
export const state = {
accessToken: '',
errorMessage: '',
errorState: false,
userEmail: localStorage.getItem('userEmail'),
userPassword: localStorage.getItem('userPassword'),
}
export const mutations = {
SET_TOKEN(state, accessToken) {
state.accessToken = accessToken
TokenService.saveToken(accessToken)
},
SET_USER(state, authUserJson) {
state.userEmail = authUserJson.email
state.userPassword = authUserJson.password
localStorage.setItem('userPassword', authUserJson.password)
localStorage.setItem('userEmail', authUserJson.email)
},
SET_ERROR(state, error) {
state.errorState = true
state.errorMessage = error.data.error_description
},
CLOSE_NOTIFICATION(state, newErrorState) {
state.errorState = newErrorState
},
}
export const actions = {
signIn({ commit, dispatch, rootState }, authUserJson) {
return UserService.authUser(authUserJson)
.then((result) => {
commit('SET_USER', authUserJson)
commit('SET_TOKEN', result.data.access_token)
dispatch('token/decodeToken', result.data.access_token, {
root: true,
})
dispatch(
'shifts/updateEventsSubscription',
rootState.token.agentId,
{
root: true,
}
)
router.push('/support')
})
.catch((error) => {
console.log(error)
if (error.response.status === 400) {
commit('SET_TOKEN', null)
commit('SET_USER', {})
commit('SET_ERROR', error.response)
} else {
console.log(error.response)
}
})
},
signOut({ commit }) {
commit('SET_TOKEN', null)
commit('SET_USER', {})
localStorage.removeItem('userPassword')
localStorage.removeItem('userEmail')
TokenService.removeToken()
router.push('/')
},
closeNotification({ commit }, newErrorState) {
commit('CLOSE_NOTIFICATION', newErrorState)
},
}
export const getters = {
getToken: (state) => {
return state.accessToken
},
errorState: (state) => {
return state.errorState
},
errorMessage: (state) => {
return state.errorMessage
},
isAuthenticated: (state) => {
return state.accessToken
},
userEmail: (state) => {
return state.userEmail
},
userPassword: (state) => {
return state.userPassword
},
}
This is websocket store: I pass the connectionId to the state in order to be able to use it in another vuex action to subscribe for new chats:
export const namespaced = true
export const state = {
connected: false,
error: null,
connectionId: '',
statusCode: '',
incomingChatInfo: [],
remoteMessage: [],
messageType: '',
ws: null,
}
export const actions = {
processWebsocket({ commit }) {
const v = this
this.ws = new WebSocket('mywebsocket')
this.ws.onopen = function (event) {
commit('SET_CONNECTION', event.type)
v.ws.send('message')
}
this.ws.onmessage = function (event) {
commit('SET_REMOTE_DATA', event)
}
this.ws.onerror = function (event) {
console.log('webSocket: on error: ', event)
}
this.ws.onclose = function (event) {
console.log('webSocket: on close: ', event)
commit('SET_CONNECTION')
ws = null
setTimeout(startWebsocket, 5000)
}
},
}
export const mutations = {
SET_REMOTE_DATA(state, remoteData) {
const wsData = JSON.parse(remoteData.data)
if (wsData.connectionId) {
state.connectionId = wsData.connectionId
console.log(`Retrieving Connection ID ${state.connectionId}`)
} else {
console.log(`We got chats !!`)
state.messageType = wsData.type
state.incomingChatInfo = wsData.documents
}
},
SET_CONNECTION(state, message) {
if (message == 'open') {
state.connected = true
} else state.connected = false
},
SET_ERROR(state, error) {
state.error = error
},
}
And finally this is the shift store (where the problem is), as you can see I have a startShift action (everything works fine with it) and then the "updateEventsSubscription" where I'm trying to wait for the response from the "startShift" action and the "processWebsocket" action. Debugging the app I realize that everything works fine with the startShift action but the websocket action sends the response after the "updateEventsSubscription" needs it causing an error when I try to make a put to that API (because it needs the connectionId parameter coming from the state of the websocket).
import ShiftService from '#/services/ShiftService.js'
export const namespaced = true
export const state = {
connectionId: '',
shiftId: '',
agentShiftInfo: '{}',
}
export const actions = {
startShift({ commit }, agentId) {
return ShiftService.startShift(agentId)
.then((response) => {
if (response.status === 200) {
commit('START_SHIFT', response.data.aggregateId)
}
})
.catch((error) => {
console.log(error)
if (error.response.status === 401) {
console.log('Error in Response')
}
})
},
async updateEventsSubscription({ dispatch, commit, rootState }, agentId) {
await dispatch('startShift', agentId)
const shiftId = state.shiftId
await dispatch('websocket/processWebsocket', null, { root: true })
let agentShiftInfo = {
aggregateId: state.shiftId,
connectionId: rootState.websocket.connectionId,
}
console.log(agentShiftInfo)
return ShiftService.updateEventsSubscription(shiftId, agentShiftInfo)
.then((response) => {
commit('UPDATE_EVENTS_SUBSCRIPTION', response.data)
})
.catch((error) => {
if (error.response.status === 401) {
console.log('Error in Response')
}
})
},
}
export const mutations = {
START_SHIFT(state, shiftId) {
state.shiftId = shiftId
console.log(`Retrieving Shift ID: ${state.shiftId}`)
},
UPDATE_EVENTS_SUBSCRIPTION(state, agentShiftInfo) {
state.agentShiftInfo = agentShiftInfo
},
}
You should convert your WebSocket action into a promise that resolves when WebSocket is connected.:
export const actions = {
processWebsocket({ commit }) {
return new Promise(resolve=> {
const v = this
this.ws = new WebSocket('mywebsocket')
this.ws.onopen = function (event) {
commit('SET_CONNECTION', event.type)
v.ws.send('message')
resolve();
}
this.ws.onmessage = function (event) {
commit('SET_REMOTE_DATA', event)
}
this.ws.onerror = function (event) {
console.log('webSocket: on error: ', event)
}
this.ws.onclose = function (event) {
console.log('webSocket: on close: ', event)
commit('SET_CONNECTION')
ws = null
setTimeout(startWebsocket, 5000)
}
});
},
}
So I realized that I have to resolve the promise on the this.ws.message instead. By doing that all my data is populated accordingly, there's still sync issues (I can't feed the websocket state at the moment because due to its async behaviour the state is not there yet when other components try to use it via: rootGetters.websocket.incomingChats for example) but I guess that's part of another question. Here's the final version of the module action:
export const actions = {
processWebsocket({ commit }) {
return new Promise((resolve) => {
const v = this
this.ws = new WebSocket('wss://ws.rubiko.io')
this.ws.onopen = function (event) {
commit('SET_CONNECTION', event.type)
v.ws.send('message')
}
this.ws.onmessage = function (event) {
commit('SET_REMOTE_DATA', event)
resolve(event)
}
this.ws.onerror = function (event) {
console.log('webSocket: on error: ', event)
}
this.ws.onclose = function (event) {
console.log('webSocket: on close: ', event)
commit('SET_CONNECTION')
ws = null
setTimeout(startWebsocket, 5000)
}
})
},
}
Anyways, thanks #Eldar you were in the right path.
I tried to change the variable data using axios, i am using vue-axios and vue cli 3.
This is the code:
const qs = require('qs')
export default {
name: 'Home',
data: function () {
return {
email: null,
errEmail: false,
baseUrl: 'https://www.example.com/isemail.php'
}
},
methods: {
next: function () {
},
err: function () {
this.axios.post(this.baseUrl + 'functions/isEmail.php', qs.stringify({
value: this.email
}))
.then(function (resp) {
this.errEmail = true
})
}
}
}
<div v-if="errEmail">Target Success</div>
Actually i am trying change the errEmail variable depend on the server callback like this:
this.errEmail = resp.data.isemail
but using constant seems not working too.
Change this
.then(function (resp) {
this.errEmail = true
})
to this
.then((resp) => {
this.errEmail = true
})
Or manually bind this
.then(function (resp) {
this.errEmail = true
}.bind(this))
Hi, currently I facing this issue. I can fix it. I have no idea why the error occurs.
Basically, I trying to save the data into DB. I used the Axios method to fetch and save data. Before this, the function was working perfectly but suddenly its causing problems. Please, anyone help me with this.
Vue.js
<script>
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import MarkdownIt from 'markdown-it'
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
var msg_editor;
Vue.use(VueAxios, axios);
const md = new MarkdownIt({
linkify: true
})
// Vue.directive('select2', {
// inserted(el) {
// $(el).on('select2:select', () => {
// const event = new Event('change', { bubbles: true, cancelable: true });
// el.dispatchEvent(event);
// });
// },
// });
// $('#condition').select2();
export default {
props: ['email_creation_link', 'email_index_route', 'email_edit_route','conditions','modules','mailtemplates'],
components: {
},
data() {
return {
template:
{
subject: '',
message: '' ,
days: '',
condition_id: 1,
},
options:[
{
display:'Client Name',
actual:'Client name'
},
{
display:'Joined Date',
actual:'Joined date'
},
{
display:'Module Name',
actual:'Module name'
},
{
display:'Last Seen',
actual:'Last seen'
},
],
showName: false,
}
},
mounted(){
var self = this;
ClassicEditor
.create(document.querySelector( "#msg"),
{
})
.then(editor => {
msg_editor = editor;
editor.model.document.on( 'change:data', () => {
self.template.message = msg_editor.getData();
});
})
.catch(error => {
console.error(error);
})
if (this.mailtemplates) {
this.template=this.mailtemplates;
}
},
methods: {
//Drag items
dragstart: function(item, e){
this.draggingItem = item;
e.dataTransfer.setData('text/plain', item.actual);
},
dragend: function(item,e) {
e.target.style.opacity = 1;
},
dragenter: function(item, e) {
this.draggingItem = item;
},
//content
replaceVariables(input)
{
let updated = input
return updated
},
//hidecontent
showHide: function(e)
{
console.log("Show "+e.target.value+ " fields")
this.showName = e.target.value == '3'
},
fetch()
{
//request data
axios.get(this.email_creation_link,this.template)
.then((res) => {
this.template = res.data.template;
})
},
save()
{
//save data to db
axios.post(this.email_creation_link, this.template)
.then((res) => {
alert('Mail sent successfull!')
})
},
addToMail: function(type, text)
{
if (type == 'message') {
this.template.message += text;
msg_editor.setData(this.template.message);
}
},
//user name replace
replaceVariables() {
return this.replaceVariables(this.options || '')
},
},
}
</script>
route.php
Route::post('api/email/create', ['as' => 'email.create', 'uses' => 'Havence\AutoMailController#create']);
Route::get('automail/mail',['as'=>'email.mail','uses' => 'Havence\AutoMailController#mail']);
Route::get('automail/index',['as'=>'email.index','uses' => 'Havence\AutoMailController#index']);
Route::get('automail/edit/{id}',['as'=>'email.edit','uses' => 'Havence\AutoMailController#edit']);
Route::get('automail/delete',['as'=>'email.delete','uses' => 'Havence\AutoMailController#destroy']);
import getAuthentication from './getAuthentication';
class Home extends React. Component {
constructor() {
super();
//this.authentication = false;
this.state = {
username: '',
password: '',
check:false,
authentication:false
};
this.err = '';
}
componentDidUpdate() {
console.log (this.state.authentication);
console.log(this.state.authentication == true);
if (this.state.check)
{
const promiseAuthentication = getAuthentication(
this.state.username,
this.state.password,
);
promiseAuthentication
.then(response => {
console.log (response.data.Success);
console.log(response.data.Success == true);
this.setState({check :false, authentication:response.data.Success});
})
.catch(error => {
// console.log(error);
this.err = error;
});
}
if (this.state.authentication == true) {
event.preventDefault();
history.push('/overview');
}
}
assignUsername = event => {
this.setState({ username: event.target.value });
};
assignPassword = event => {
this.setState({ password: event.target.value });
};
handleSubmit = () => {
this.setState({ check:true });
};
==============================================================
getAuthentication.js
import axios from 'axios';
function getAuthentication(username, password) {
const authenticationConfig = {
Email: username,
Password: password,
};
return axios.post(
'http://localhost:5002/login/confirmation',
authenticationConfig,
);
}
export default getAuthentication;
In the above code my this.state.Authentication is not getting updated to true
I am trying to update its value in axios promise.
Can someone please tell me what's wrong? I mean I have tried everything but I am not able to proceed.
How do I change the state of Authentication object and switch new window?
I have a second file that is returning the axios promise where promise value is "undefined".. How do I make async call and resolve this issue ??
componentDidUpdate is wrapped in if (this.state.check). Nothing in the code you pasted sets this.state.check to true. Set this.state.check: true.
Thanks for reading my question in advance. I'm using the dva and Ant Design Mobile of React handling phone register function.
Before sending the verify code, I will judge if the phone has been registered. If yes, it will Toast " This phone has been registered".
Now, the return value is correct:
const mapStateToProps = (state) => {
console.log(state.register.message)
}
// {code: 221, message: "This phone has been registered"}
So I write it as:
const mapStateToProps = (state) => ({
returnData: state.register.message
})
And then when I click the button, it will dispatch an action (send a request):
getVerifyCode() {
const { form, returnData } = this.props;
const { getFieldsValue } = form;
const values = getFieldsValue();
this.props.dispatcher.register.send({
phone: values.phone,
purpose: 'register',
})
// if(returnData.code === 221){
// Toast.fail("This phone has been registered", 1);
// } else {
// Toast.success("Send verify code successfully", 1);
// }
}
But when I tried to add the if...else condiction according to the return value
if(returnData.code === 221){
Toast.fail("This phone has been registered", 1);
} else {
Toast.success("Send verify code successfully", 1);
}
only to get the error:
Uncaught (in promise) TypeError: Cannot read property 'code' of
undefined
I supposed it's the problem about aynchromous and tried to use async await:
async getVerifyCode() {
...
await this.props.dispatcher.register.send({
phone: values.phone,
purpose: 'register',
})
}
But get the same error
Cannot read property 'code' of undefined
I wonder why and how to fix this problem ?
added: this is the models
import * as regiserService from '../services/register';
export default {
namespace: 'register',
state: {},
subscriptions: {
},
reducers: {
save(state, { payload: { data: message, code } }) {
return { ...state, message, code };
},
},
effects: {
*send({ payload }, { call, put }) {
const { data } = yield call(regiserService.sendAuthCode, { ...payload });
const message = data.message;
yield put({ type: 'save', payload: { data },});
},
},
};
handle conditions in the models solved the problem:
*send({ payload }, { call, put }) {
const { data } = yield call(regiserService.sendAuthCode, { ...payload });
if(data.code === 221){
Toast.fail("This phone has been registered", 1);
} else {
Toast.success("Send verify code successfully", 1);
}
yield put({ type: 'save', payload: { data }});
}