Wednesday 31 March 2021

Vue.js Change the Value of a Data item from a Method.

This is pretty simple but I found it difficult to search for on Google. So just noting this down here in case I forget it. So I have a value in my ‘data’ that’s being output in the template. But I need to manipulate it and run a function on it. For this, we can put the functions in ‘methods'.

export default
props: {
survey: {
type: Object,
required: true
}
},
data(){
return{
survey_date: new Date(this.convert_date(                 this.survey.survey_date)).toISOString().substr(0, 10),
}
},
methods: {
convert_date(value){
console.log(this.formatDate(value))
return this.formatDate(value)
},
formatDate(date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();

if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;

return [year, month, day].join('-');
}

 

Tuesday 30 March 2021

Vue.js - How to get the value of Date from $refs

How to get the value of Date from $refs  - however this may also help you find the solution to other similar issues.  I'm blogging this as I couldn't find a written solution on the the net.  And got to the solution by looking hard enough. 

So the HTML is as follows.  This is using 'v-date-picker' ( vuetify ) 


<v-date-picker
:v-model="survey_date"
light
ref="Date"
label="Date"
id='survey_date'
prepend-icon="date_range"
filled
></v-date-picker>


And I need to know how to pick up the date in the $ref

In the ‘SCRIPT’ lets ‘console.log’ the ref

const new_date = this.$refs.Date;
console.log(new_date);


This outputs an object - in here eventually I opened ‘emitInput’ - I’d seen in another post that values were kept in ‘input’ , so it seemed to make sense.


Drilling down further I saw ‘inputDate’



Using this I can access that date ‘2021-03-09’ which is what I want.

const new_date = this.$refs.Date.inputDate;

Monday 29 March 2021

Vue.js to Firebase - how to pass a date into Firebase

 Here are the different field types that can be excepted by Google Firebase.

> String 

> Number

> Boolean
> Map
> Array
> Null
> Timestamp

> Geopoint


Hopefully, this example will be a blueprint on how to import the other Data types too.

The documentation for the following code can be found at Timestamp  |  Firebase

The followin method in your vue.js code should work


async submit() {
if(this.$refs.form.validate()){
this.loading = true
const survey = {
title: this.title,
Date: firebase.firestore.Timestamp.fromDate(new Date()),
}
const db = await firebase.firestore();
db.collection('survey').add(survey).then(docRef => {
this.loading = false
this.snackbar = true
}).catch(error => {
console.log(error.message);
})
})
})
}
}

 

If you’re passing in your own date from a form then this is how I do this in my code.


<!-- HTML -->

<v-date-picker v-model="survey_date"
light
></v-date-picker>

<!-- CODE -->

export default {
data() {
return {
survey_date: new Date().toISOString().substr(0, 10),
snackbar: false
}
...
Date: firebase.firestore.Timestamp.fromDate(new Date(this.survey_date)),
...

 

Which works fine for me.

And bring the data back in from Firebase you’d use

this.surveys.push(
{
...
survey_date: Survey.Date.toDate(),

Tuesday 23 March 2021

Vue.js and Vuetify : Value in for loop doesn't match when using v-dialog

 This issue is relevant if you are using Vue.js and Vuetify.  And was occurring  for me when I was adding a  Dialog ( Pop out ) box in Vuetify .  

Take a look at this code as an example.  

<v-btn
@click.stop="innerdialog = true"
outlined
fab
color="transparent"
height=400
>View image {{ photo.id }}</v-btn>
<v-dialog v-model="innerdialog">
<v-card>
<v-card-title class="headline">
<v-img
:src="photo.id"
>
</v-img>
</v-card-title>

<v-card-actions>

</v-card-actions>
</v-card>
</v-dialog>


So if my array of images is 6 items then oddly the first call to the value 'photo.id' would be  '1' and the second 6 .  And therefore always showing the last photo in my array. 

So I came up with the following solution.  This uses a variable to store the count of where we are to grab it again in the v-card in our v-dialog.  Note: the count is one off so I had to -1 .  The count of where we are is loaded in Click event of the button. 


<v-btn
@click.stop="innerdialog = true; imagecounter = photo.id"
outlined
fab
color="transparent"
height=400
>View image {{ photo.id }}</v-btn>
<v-dialog v-model="innerdialog">
<v-card>
<v-card-title class="headline">
<v-img
:src="photos[imagecounter-1].image_url"
>
</v-img>
</v-card-title>

<v-card-actions>

</v-card-actions>
</v-card>
</v-dialog>


And in the Script section. 

data(){
return{
innerdialog: false,
width: 800,
imagecounter: 1
}
}




Thursday 18 March 2021

Vue.js - Calling a 'Component' from an Iteration in a .vue page

I just thought I’d share this bit of code with you. So I have a card with full-page PopUps ( dialogs) but to save the trauma of putting all of this on one page I am using components and then calling each one with ‘if’ statements ( as it’s inside a loop )

So each of your components goes on their own pages in the ‘src/components’ folder.

 


We then need to import all of these into our SCRIPT section


import PhotosView from '../components/PhotosView.vue'
import LocationView from '../components/LocationView.vue'
import SealsView from '../components/SealsView.vue'
import DisturbanceView from '../components/DisturbanceView.vue'
import AdditionalView from '../components/AdditionalView.vue'
import PhotosEditor from '../components/PhotosEditor.vue'
import LocationEditor from '../components/LocationEditor.vue'
import SealsEditor from '../components/SealsEditor.vue'
import DisturbanceEditor from '../components/DisturbanceEditor.vue'
import AdditionalEditor from '../components/AdditionalEditor.vue'



Then register the components

export default {
components: {
PhotosView,
LocationView,
SealsView,
DisturbanceView,
AdditionalView,
PhotosEditor,
LocationEditor,
SealsEditor,
DisturbanceEditor,
AdditionalEditor
},



Now in the HTML I have a loop that I want to make a decision on which component to show depending on the value. I solve this puzzle with the following code


<v-container v-if="item.text === 'Photos'">
<PhotosView/>
</v-container>
<v-container v-if="item.text === 'Location'">
<LocationView/>
</v-container>
<v-container v-if="item.text === 'Seals'">
<SealsView/>
</v-container>
<v-container v-if="item.text === 'Disturbance'">
<DisturbanceView/>
</v-container>
<v-container v-if="item.text === 'Additional'">
<AdditionalView/>
</v-container> 

  

Wednesday 17 March 2021

Vue.js Vuetify - v-dialog not shutting the PopUp window the second time.

 So here's what's happening 

The first time you open the Popup ( dialog ) and close it , it works fine the second time it crashes. 

In the console log I can see the following issue repeated a heap of times. 

VDialog.js?169a:226 Uncaught RangeError: Maximum call stack size exceeded.

    at VueComponent.onFocusin (VDialog.js?169a:226)

    at VueComponent.onFocusin (VDialog.js?169a:226)

    at VueComponent.onFocusin (VDialog.js?169a:226)



On search for the issue I found the following useful post . https://stackoverflow.com/questions/59913415/error-and-wrong-behaviour-on-close-component-from-parent-using-vuetify-v-dialog


The fix for me was 

<v-dialog
v-model="dialog"
fullscreen
:retain-focus="false"
>

Friday 12 March 2021

v-fileinput : Invalid prop: custom validator check failed for prop "value". found in ..

I'm seeing this error in the console log when running my code.  

The solution was to the data value on my image file to an array.  

HTML


<v-file-input chips multiple v-model="imageFile" label="Survey Photos" ></v-file-input>



SCRIPT


export default { data() { return { imageFile: [],