Wednesday, 19 May 2021

Setting up Firebase Hosting with your Google Domain.

 I managed to sort this issue with the help of this YouTube video, its the last 2 minutes https://www.youtube.com/watch?v=5-5q5GObvSI 


In your Firebase administration area, go to 'Hosting' .  

From here you'll need to 'Add custom domain', or if you've already done that bit then you can click on the view button, and then goto the 'Advanced' mode.  

What we're looking for is the 'value' for TXT type.  Once you have this, then copy it and log into 'Google Domains.'


In the DNS settings for Google Domains scroll down to 

Custom resource records , here I deleted what I had before .  
1. Leave the name as '@'
2. Selected 'TXT' from the Type dropdown. 
3. Pasted in my 'TXT' value into the 'Data' entry. 
4. Waited 24 hrs !

Tuesday, 18 May 2021

Vue.js Vuetify: V-checkbox - Value not changing from a Data

 So what i had is a V-checkbox like this

<v-checkbox
:label="Hub.name"
color="info"
:value=preselected
hide-details ></v-checkbox>
<script>

export default {
data() {
return {
preselected: true
};


But ‘preselected’ would not pass through as True.

I can change the ‘Value’ call to 'value=true'

And then to check that the Checkboxes will actual be forced to be ‘true’ directly.

I then managed to fix this by using ‘input-value’ instead. The following example works.

<v-checkbox :label="Hub.name"
color="info" :input-value=preselected hide-details ></v-checkbox>

 

And we can pick this value up in our Submit method like this

if(this.$refs.form.validate()){
this.$refs.checkbox.forEach((checkbox) => {
if (checkbox.inputValue != checkbox.isActive ){
console.log('checkbox.id)
if ( checkbox.isActive === true ){
// console.log('Add this hub from the array')
hub_ids.push(checkbox.id);
}
else {
hub_ids = hub_ids.filter(item => item !== checkbox.id);
// console.log('Remove this hub from the array')
}

 

 

Friday, 14 May 2021

Using 'Typeof' in Vue.js Testing to fix errors.

 

Using Chai in Vue.js - for some reason my test looked like this . 

it('Home page message', function(done) {
request('http://localhost:8080' , function(error, response, body) {
expect(body.$('div.app').text().to.have.string('Cornwall'));
done();
});
});


This was returning the error 

Uncaught TypeError: body.$ is not a function


To fix this wanted to see 'body' was, so added the code 

console.log(body)


The 'console.log' prints out in your terminal.  The print out looks like a string , and this can be confirmed with. 

console.log(typeof body)

From here on I can use 'search' on the string for the text I'm looking for . 

var expect = require('chai').expect;
var request = require('request');

it('Home page message', function(done) {
request('http://localhost:8080' , function(error, response, body) {
expect(body.search('Cornwall'));
done();
});
});

Additionally if you want to turn the 'body' into DOM objects then we can use 'jsdom'

I'll have a code example for this soon. 

Tuesday, 11 May 2021

Vue.js How to close a v-dialog box from inside the component.


This is easy enough to do when you have all your code on one page. You can set a value in ‘data’ of the script and then set that to either true or false to open and close the box. Take this example of my Message box, also note how you can manipulate the message and colors to your needs rather than rewriting. HTML


<v-snackbar v-model="snackbar" :timeout="4000" top :color="error_message_color">
<span>{{ error_message }}</span>
<v-btn outlined @click="snackbar = false">Close</v-btn>
</v-snackbar>




SCRIPT 

export default {
data() {
return {
...
snackbar: false,
error_message: "Awesome! You've updated this users roles.",
error_message_color: 'success'
};
},

// to fire this snackbar up from a method you just need to add ->
this.snackbar = true;

// if you want to fire up with a different message other than the defaults

if ( currentUser.email === Profile.email && action === 'remove' && role.toLowerCase() === 'admin'){
this.error_message_color = 'error';
this.error_message = 'Admins cannot remove their own admin role.';
this.snackbar = true;
return;
}

 However, although this code is good on one page if we’ve opened up the Dialog from a parent page like the following then unfortunately that won’t work.


// HTML
<RolesDialog :profile="profile" />

//SCRIPT
import RolesDialog from './RolesDialog.vue'

export default {
components: {
RolesDialog
},
data() {
return {
roles_dialog: false
};

With the above code, we cannot shut the box from our v-dialog box that we’ve opened.

The following code should work, and that works using $emit

Our call to the component.

<RolesDialog :profile="profile" @close-dialog="closeDialog" />

SCRIPT


data() {
return {
...
dialog: false,
roles_dialog: false
};
},

methods: {
closeDialog: function(){
console.log('close dialog 2');
this.dialog = false;
this.roles_dialog = false
}
},
}

In the CHILD component.


// HTML

<v-btn
color="blue darken-1"
text
@click="closeDialog"
>

// SCRIPT

methods: {
closeDialog: function(){
console.log('close dialog 1');
this.$emit('close-dialog')
}
}

  This should now work.












Thursday, 29 April 2021

Vue.js - Passing additional arguments with the Event through @click function.

So here what I would like to do is send some data that I have in my loop through to the function that I'm using in my @click to the method I'm using ( that interacts with Firebase ) . 

Originally my call to this method from 'v-btn' looked like this. 

<v-btn
color="deep-purple dark"
text
@click="makeAdmin"
>


The event here passes through without us having to add the arguments. It's implied.

async makeAdmin(e) {
const functions = firebase.functions();
e.preventDefault();

We could write @click="makeAdmin(event)"

if we wanted to be explicit.  

To pass through an argument from the loop we are in then the following example works. 

<v-list-item
v-for="(Profile) in profiles"
:key="Profile.id"
>
<v-avatar
color="primary"
size="32"
>
<v-img :src='Profile.image'
max-width='100'
overline
/>
</v-avatar>
<v-list-item-content>

<v-list-item-title >{{Profile.firstname}} {{Profile.surname}}</v-list-item-title>
</v-list-item-content>
<v-card-actions>
<v-form
ref="form"
id="makeAdmin"
>
<v-btn
color="deep-purple dark"
text
@click="makeAdmin(Profile.email, $event)"
>
Make Admin
</v-btn>

And the method will look like. 

async makeAdmin(user_email, e) {
const functions = firebase.functions();
e.preventDefault();
const addAdminRole = functions.httpsCallable('addAdminRole');
addAdminRole({email: user_email}).then(result => {
console.log('successful ! ' + result)
})
},

Thursday, 8 April 2021

Vue.js - Vuetify forms 'v-text-field' input Errors not in Red

 So, I had this weird issue where I have some of my form Errors coming up in red ( preferred ) and others not. 



Having checked both pieces of code and having been given a clue of what to look for from the CSS 


What I needed to do is wrap the form where the Errors aren't showing in Red with a <v-app> tag. 

<template>
<v-app id="app">
<v-container

Thursday, 1 April 2021

How to add MapState to the Computed items - calling Vuex in Vue.js

 So after using several Form validations I’m using in the form from Vuex Store, my code looks like this


computed:{
swellitems(){
return this.$store.state.swellitems
},
weather_sky(){
return this.$store.state.weather_sky
},
weather_wet_dry()
return this.$store.state.weather_wet_dry
},
survey_type(){
return this.$store.state.survey_type
},
one_to_three(){
return this.$store.state.one_to_three
},
wind_force(){
return this.$store.state.wind_force
},
wind_direction(){
return this.$store.state.wind_direction
},
sea_state(){
return this.$store.state.sea_state
},
tide_state(){
return this.$store.state.tide_state
},
tide_movement(){
return this.$store.state.tide_movement
},


Way before this point I’m thinking there must be a better way to deal with this ( although laziness means I don’t hunt it down until it gets this bad. ).
The method we want to use is ‘mapState’

computed:{
...mapState(['swellitems', 'weather_sky', 'weather_wet_dry','survey_type',
'one_to_three', 'wind_force', 'wind_direction','sea_state', 'tide_state', 'tide_movement'])
}

The ‘…' won’t work straight out of the box though. We’ll need to install ‘bable’

INSTALLING BABEL FOR VUEX

Babel-Plugin-Vuex-Store (shortly vx for Vuex) packs along a couple of features to simplify your Vuex-related coding. Installation and usage.

npm install babel-plugin-vuex-store

and then

npm install babel-preset-stage-2 --save-dev

You'll also need to import mapState into your Script

import { mapState } from 'vuex';

After this, my code works and looks my organised :) .