Vue Date Dropdown's value should be updated when conditions is changed. Currently, the watch successfully updates selectedDate but fails to re-render date-dropdown.
<template>
<div id="app">
<div>{{selectedDate}}</div> <-- this value is updated after getFilter()
<date-dropdown default="1995-01-10" v-model="selectedDate"/> <-- this component holds old/default value: 1995-01-10
<b-button #click="getFilter()" variant="primary">update</b-button>
</div>
</template>
<script>
import axios from 'axios';
import DateDropdown from "vue-date-dropdown";
const SERVER_URL = 'http://localhost:9000';
const instance = axios.create({
baseURL: SERVER_URL,
timeout: 1000
});
export default {
name: 'App',
components: {
DateDropdown
},
props: {
},
data () {
return {
selectedDate: '',
filter: {
name: 'Filter22With2Conditions',
conditions: [
{ type: 'date', clause: 'until', data: '02.02.1990' },
]
}
...
watch: {
filter: function () {
this.selectedDate = this.filter.conditions[0].data;
}
},
methods: {
getFilter: function() {
let self = this;
instance.get('/api/filters?name=Filter22With2Conditions')
.then(function(response) {
console.log('getFilter:response: ' + JSON.stringify(response.data))
self.filter = response.data;
})
.catch(function(error) {
console.log('getFilter: error: ' + error)
self.errors.push(error);
})
},
...
}
Related
I have a datatable and I want to pass the data according to the api that returns a json using findAll() from the sequelize..
But in console.log when I call the getUser method it returns the data with the data. But when you insert data into the datatable: it is informing you that it has no data.
Example datatable using in code: https://vuejsexamples.com/a-vue-plugin-that-adds-advanced-features-to-an-html-table/
<template>
<div>
<data-table v-bind="bindings"/>
</div>
</template>
<script>
import ActionButtons from "../Components/ActionButtons"
import axios from "axios"
export default {
name: 'Usuarios',
data(){
return {
user: this.user,
errors: []
}
},
computed: {
bindings() {
return {
data: this.user,
lang: "pt-br",
actionMode: "single",
columns: [
{
key:"code",
title:"Código"
},
{
key:"name",
title:"Nome"
},
{
key:"login",
title:"Login"
},
{
key:"cpf",
title:"CPF"
},
{
key:"actions",
title:"Ações",
component: ActionButtons,
},
],
}
}
},
methods:{
getUser() {
axios
.get("http://localhost:3005/users")
.then((res) => {
this.user = res.data;
})
.catch((error) => {
console.log(error);
});
},
}
};
</script>
I believe the reason it doesn't work is because the getUser() method is defined but not called.
If you move the async request into a created() lifecycle hook, the request will be made before the component is mounted, so the table should have access to the data. https://v3.vuejs.org/api/options-lifecycle-hooks.html#created
I think this will really help you.
<template>
<v-card>
<v-card-title>
Liste du Personnel
</v-card-title>
<v-card-text class="mt-3">
<main>
<data-table v-bind="listing_personnel" #actionTriggered="handleAction"/>
<br>
</main>
</v-card-text>
</v-card>
</template>
<script>
import axios from "axios";
import ActionButtons from "./ActionButtons"
export default {
data(){
return {
user: [],
errors: []
}
},
created() {
this.getPersonnel();
},
methods: {
handleAction(actionName, data) {
console.log(actionName, data);
window.alert("check out the console to see the logs");
},
async getPersonnel() {
try {
const response = await axios.get("SeletAllUsers");
this.user = response.data;
}
catch (error) {
console.log(error);
}
},
},
computed: {
listing_personnel() {
return {
data: this.user,
actionMode: "multiple",
columns: [
{
key: "user_matricule",
title: "Matricule"
},
{
key: "user_lastname",
title: "Noms"
},
{
key: "user_firstname",
title: "Prénoms"
},
{
key: "user_contact1",
title: "Contact"
},
{
key: "user_email",
title: "Email"
},
{
key:"actions",
title:"Actions",
component: ActionButtons,
},
]
};
}
},
};
</script>
/* preferably put this in its main.js
axios.defaults.baseURL = 'http://localhost:8080/';*/*
I am new to VueJs and Laravel. I am trying to build a chat app following this tutorial, and my problem is that I am not able to pass a CONTACT variable (object type) from ChatApp.vue to Conversation.vue. The console gives this error
[Vue warn]: Invalid prop: type check failed for prop "contact". Expected Object, got Null
found in ---> <MessageFeed> at resources/js/officer/components/MessageFeed.vue
<Conversation> at resources/js/officer/components/Conversation.vue
<ChatApp> at resources/js/officer/components/ChatApp.vue
<Root>
first the variable has to pass through ChatApp to Conversation and then to MessageFeed. I tried printing it on console, in ChatApp.vue, it printed the variable's property i.e. name but when I try to print it in Conversation.vue, it says it is null and also gives the above error.
please see the code below:
ChatApp.vue
<template>
<div class="chat-app">
<Conversation :contact="selectedContact" :messages="messages" #new="saveNewMessage"/>
<ContactsList :contacts="contacts" #selected="startConversationWith"/>
</div>
</template>
<script>
import Conversation from "./Conversation";
import ContactsList from "./ContactsList";
const axios = require('axios');
export default {
props: {
user: {
type: Object,
required: true
}
},
data() {
return {
selectedContact: null,
messages: [],
contacts: []
}
},
mounted() {
Echo.private(`messages.${this.user.id}`)
.listen('NewMessage', (e) => {
this.handleIncoming(e.message);
});
console.log(this.user);
axios.get('/officer/contacts')
.then((response) => {
this.contacts = response.data;
console.log("chatapp1: " + this.contacts[0].name);
})
.catch((error) => {
// handle error
console.log(error);
});
},
methods: {
startConversationWith(contact) {
axios.get(`/officer/conversation/${contact.id}`)
.then((response) => {
this.message = response.data;
this.selectedContact = contact;
console.log("chatapp: " + this.selectedContact.name);
});
},
saveNewMessage(message) {
this.messages.push(message);
},
handleIncoming(message) {
if (this.selectedContact && message.from === this.selectedContact.id) {
this.saveNewMessage(message);
return;
}
this.updateUnreadCount(message.from_contact, false);
},
updateUnreadCount(contact, reset) {
this.contacts = this.contacts.map((single) => {
if (single.id !== contact.id) {
return single;
}
if (reset)
single.unread = 0;
else
single.unread += 1;
return single;
})
}
},
components: {Conversation, ContactsList}
}
Conversation.vue
<template>
<div class="conversation">
<h1>{{ contact ? contact.name : 'Select a Contact' }}</h1>
<MessagesFeed :contact="contact" :messages="messages"/>
<MessageComposer #send="sendMessage"/>
</div>
</template>
<script>
import MessagesFeed from './MessageFeed';
import MessageComposer from './MessageComposer';
export default {
props: {
contact: {
type: Object,
default: null
},
messages: {
type: Array,
default: []
}
},
mounted() {
console.log("conversation: "+this.contact);
},
methods: {
sendMessage(text) {
if (!this.contact) {
return;
}
console.log(text);
axios.post('/conversation/send', {
contact_id: this.contact.id,
text: text
}).then((response) => {
this.$emit('new', response.data);
})
}
},
components: {MessagesFeed, MessageComposer}
}
MessageFeed.vue
<template>
<div class="feed" ref="feed">
<ul v-if="contact">
<li v-for="message in messages" :class="`message${message.to == contact.id ? 'sent' : 'received'}`"
:key="message.id">
<div class="text">
{{message.text}}
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
contact: {
type: Object,
required: true
},
messages: {
type: Array,
required: true
}
},
methods: {
scrollToBottom() {
setTimeout(() => {
this.$refs.feed.scrollTop = this.$refs.feed.scrollHeight - this.$refs.feed.clientHeight;
}, 1);
}
},
watch: {
contact(contact) {
this.scrollToBottom();
},
messages(messages) {
this.scrollToBottom();
}
}
}
please, let me know what am I missing here.
Because you konfigurated it to be an Object but you declared it on the initial state as null
selectedContact: null
That should be an object
It should look something like this i guess:
selectedContact: {
id:0
}
I fixed the issue.
This was due to axios.get() response thing. It was fetching data from database after a couple of minutes and the Conversation.vue and ContactList.vue were mounting immediately so they were not getting data.
With the help of my friend, it was fixed by loading the component only when axios have got all the contactlist from database and the very first contact have been passed to the Conversation.vue component i.e using v-if property of component.
I'm trying to pass data from vue component to blade file. I try to create props but it's didn't work for me. Is it any possible to pass the object to props to get the data? I'm new laravel. I want to pass data which subject, message, days, condition and module name to blade file(view).
I kept searching for this but couldn't find an answer that will make this clear.
Thanks!
blade.php
<div id="app">
<email-component
email_edit_route="{{ route('havence.automail.edit',['id'=>$mailTemplates->id]) }}"
>
</email-component>
</div>
Vue.js
<script>
import Vue from 'vue'
import axios from 'axios'
import MarkdownIt from 'markdown-it'
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
var msg_editor;
const md = new MarkdownIt({
linkify: true
})
export default {
props: ['email_creation_link', 'email_index_route', 'email_edit_route','conditions','modules'],
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);
})
},
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 !== ''
},
fetch()
{
//request data
axios.get(this.email_index_route,this.template)
.then((res) => {
this.template = res.data.template;
})
},
save()
{
//save data to db
axios.post(this.email_index_route, this.templates)
.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>
Quick solution. : why not store data in local storage and fetch it from laravel blade ?
Next solution: you can fire global event from vue and listen on laravel blade .
why dont you send the data through ajax post call and get the data from the controller ?
then pass the data object to blade template.
I'm using vuex to manage the state in my application and doing one way binding with my form.
<script>
import { mapGetters } from 'vuex'
import store from 'vuex-store'
import DataWidget from '../../../../uiComponents/widget'
export default {
data () {
return {
isEdit: false,
msg: {
id: 0,
content: '',
isEnabled: false
}
}
},
components: {
DataWidget
},
computed: mapGetters({
messageId: 'messageId',
messageContent: 'messageContent',
isMessageEnabled: 'isMessageEnabled',
isMessageValid: 'isMessageValid'
}),
methods: {
onSave () {
store.dispatch('saveMessage', this.msg, { root: true })
if (this.isMessageValid) {
this.isEdit = !this.isEdit
}
}
},
created () {
this.msg.id = this.messageId
this.msg.content = this.messageContent
this.msg.isEnabled = this.isMessageEnabled
}
}
</script>
<b-form-textarea id="content" v-model="msg.content" :rows="3" required aria-required="true" maxlength="250"></b-form-textarea>
On load, the values on created() are not binded until I perform an action on the page or refresh the page.
I have tried mounted () hooked same thing.
My Vuex store (Message Module) looks like this:
const state = {
messageId: 0,
messageContent: '',
isMessageEnabled: false,
isMessageValid: true
}
const getters = {
messageId: state => state.messageId,
messageContent: state => state.messageContent,
isMessageEnabled: state => state.isMessageEnabled,
isMessageValid: state => state.isMessageValid
}
const actions = {
getMessage ({commit, rootGetters}) {
api.fetch('api/Preference/Message', rootGetters.token)
.then((data) => {
commit(types.MESSAGE_LOAD, data)
})
}
}
const mutations = {
[types.MESSAGE_LOAD] (state, payload) {
state.messageId = payload ? payload.id : 0
state.messageContent = payload ? payload.content : ''
state.isMessageEnabled = payload ? payload.enabled : false
}
}
export default {
state,
getters,
actions,
mutations
}
and I have a global action (action.js) the gets multiple data:
export const loadSetting = ({ commit, rootGetters }) => {
api.fetchAsync('api/Preference/all', rootGetters.token)
.then((data) => {
commit(types.MESSAGE_LOAD, data.message)
commit(types.HELPDESK_LOAD, data.helpDesk)
commit(types.VOLUME_LOAD, data.volumes)
commit(types.DOWNLOAD_LOAD, data.downloadService)
})
}
My api call:
async fetchAsync (url, token = '') {
let data = await axios.get(HOST + url, {
headers: {
'Authorization': 'bearer ' + token
}
})
return data
}
The problem is your'e calling an async method in Vuex but in the created method, you're treating it like a sync operation and expect to get a value.
You need to use the computed properties you created since they are reactive and will update on every change. In order to make the computed writeable change it to be like this:
computed: {
...mapGetters({
messageId: 'messageId',
isMessageEnabled: 'isMessageEnabled',
isMessageValid: 'isMessageValid'
}),
messageContent(){
get () {
return this.$store.getters.messageContent
},
set (value) {
//this is just an example, you can do other things here
this.$store.commit('updateMessage', value)
}
}
}
And change the html to use messageContent:
<b-form-textarea id="content" v-model="messageContent" :rows="3" required aria-required="true" maxlength="250"></b-form-textarea>
For more info refer to this: https://vuex.vuejs.org/en/forms.html
I have have view router set up:
router.map({
'/tracks/:id': {
component: SingleTrack
}
})
And this is my component (which works with a hard coded URL):
var SingleTrack = Vue.component('track', {
template: '#track-template',
data: function() {
return {
track: ''
}
},
ready: function() {
this.$http.get('//api.trax.dev/tracks/1', function (data) {
this.$set('track', data.track)
})
}
});
How do I pass the url/:id to the end of the $http.get string so i can grab the correct data dynamically when that route in loaded, something like:
ready: function(id) {
this.$http.get('//api.trax.dev/tracks/' + id, function (data) {
this.$set('track', data.track)
})
}
You should be able to get the route parameter from the component $route property :
var itemId = this.$route.params.id;
this.$http.get('//api.trax.dev/tracks/' + itemId, function (data) {
this.$set('track', data.track)
})
See more details in vue.js router documentation
For Best Practises:
index.js(router)
{
path: '/tracks/:id',
name: 'SingleTrack',
component: SingleTrack,
props: (route) => {
const id = Number.parseInt(route.params.id);
return { id }
},
}
SingleTrack.vue
props: {
id: {
type: Number,
required: true,
},
},
mounted(){
this.$http.get('//api.trax.dev/tracks/' +this.id, function (data) {
this.$set('track', data.track)
})
}