Related
I have a variable that is called "name" inside my data(). And this is updated once I fetch this value from firebase using created() like this:
created: async function fetchDataFromFirebase() {
this.email = this.getCurrentUser().email
await this.doctorsCollection.doc(this.email).get().then(async (doc) => {
this.name = await doc.data().title + ' ' + await doc.data().firstName + ' ' + await doc.data().lastName
this.speciality = await doc.data().speciality
this.phone = await doc.data().phone
this.profilePicture = doc.data().img == null || doc.data().img === '' ? 'https://firebasestorage.googleapis.com/v0/b/healthy-wo.appspot.com/o/doctors%2FMantraHW-T-Coral-01.png?alt=media&token=2ae855cb-c96d-4b97-b813-c844f9e0e871':doc.data().img
// getCurrentAge will give the difference in years between today and the Date object you're passing
this.age = this.getCurrentAge(new Date((await doc.data().birthDate).toMillis())) + ' años'
// memberDate is a variable that holds the date this user was registered but in Date object format
let memberDate = new Date((await doc.data().subscriptionStart).toMillis())
this.member_duration = memberDate.getDate() + '/' + (memberDate.getMonth()+1<10 ? '0'+(memberDate.getMonth()+1):memberDate.getMonth()+1) + '/' + memberDate.getFullYear()
})
},
My problem here though, is that I must wait for this variable to update and then asign it to a new variable inside data() too, called query. But everytime I reference it as this.name I get an error because name is undefined. Here's my query I'm trying to submit
query: firebase.firestore().collection('feed').limit(3).where('author', '==', /*here goes name*/),
I must have this query variable in data() because then I got to pass it as a prop to a new component:
<post-card
v-bind:query="query"
></post-card>
Here's my data() too:
data() {
return {
doctorsCollection: firebase.firestore().collection('doctors'),
name: 'hello',
query: firebase.firestore().collection('feed').limit(3).where('author', '==', this.name),
speciality: '',
member_duration: '',
email: '',
phone: '',
age: '',
profilePicture: '',
dialog: false
}
},
I've just solved it by placing the query change inside created.
created: async function fetchDataFromFirebase() {
this.email = this.getCurrentUser().email
await this.doctorsCollection.doc(this.email).get().then(async (doc) => {
this.name = await doc.data().title + ' ' + await doc.data().firstName + ' ' + await doc.data().lastName
this.speciality = await doc.data().speciality
this.phone = await doc.data().phone
this.profilePicture = doc.data().img == null || doc.data().img === '' ? 'https://firebasestorage.googleapis.com/v0/b/healthy-wo.appspot.com/o/doctors%2FMantraHW-T-Coral-01.png?alt=media&token=2ae855cb-c96d-4b97-b813-c844f9e0e871':doc.data().img
// getCurrentAge will give the difference in years between today and the Date object you're passing
this.age = this.getCurrentAge(new Date((await doc.data().birthDate).toMillis())) + ' años'
// memberDate is a variable that holds the date this user was registered but in Date object format
let memberDate = new Date((await doc.data().subscriptionStart).toMillis())
this.member_duration = memberDate.getDate() + '/' + (memberDate.getMonth()+1<10 ? '0'+(memberDate.getMonth()+1):memberDate.getMonth()+1) + '/' + memberDate.getFullYear()
})
this.query = firebase.firestore().collection('feed').limit(3).where('author','==', this.name.toString())
},
data() {
return {
doctorsCollection: firebase.firestore().collection('doctors'),
name: 'hello',
query: 'null',
speciality: '',
member_duration: '',
email: '',
phone: '',
age: '',
profilePicture: '',
dialog: false
}
},
And also using a v-if statement inside my component. So it won't be rendered unless query is different from an initial string.
<post-card
v-if="query !== 'null'"
v-bind:query="query"
></post-card>
Hallo I am stuck with the following:
I am working on a Vue application that consists of multiple component. Now i have a component that uses vee-validate. Only for a custom validation I want change a data element in the component data() object. Only if I try this the following Exception pops up: cannot set property 'kenteken' of undefined
The code is as follow:
<script>
import {Validator} from 'vee-validate';
import nl from 'vee-validate/dist/locale/nl';
const isKenteken = (value) =>{
app.loader.kenteken= true;
return axios.post('/api/validate/kenteken', {kenteken: value}).then((response) => {
// Notice that we return an object containing both a valid property and a data property.
app.loader.kenteken = false;
app.voertuig.merk = response.data.Algemeen.Merk;
app.voertuig.model = response.data.Algemeen.Type;
app.voertuig.brandstof = response.data.Algemeen.Brandstof.toLowerCase();
app.voertuig.type_id = response.data.Algemeen.TypeId;
app.voertuig.model_id = response.data.Algemeen.ModelId;
app.voertuig.merk_id = response.data.Algemeen.MerkId;
console.log(response.data.Algemeen);
return {
valid: true,
data: {
message: response.data.Algemeen,
}
};
}, (error) => {
console.log(error);
app.voertuig.kenteken = '';
app.loader.kenteken_onbekend = 1;
app.loader.kenteken = false;
return false;
});
};
Validator.localize('nl', nl);
Validator.extend('kenteken', {
validate:isKenteken,
getMessage: (field, params, data) => {
loader.kenteken = false;
voertuig.merk = data.message.Merk;
}
});
export default {
name: "app",
data() {
return {
voertuig: {
kenteken: '',
model: '',
model_id: '',
type: '',
type_id: '',
merk: '',
merk_id: '',
brandstof: '',
schadevrijejaren: ''
},
bestuurder: {
geboortedatum: '',
postcode: '',
huisnummer: '',
straat: '',
woonplaats: ''
},
loader: {
kenteken_onbekend: false,
kenteken: false,
},
}
},
mounted() {
var self = this;
}
}
</script>
So how to access the load.kenteken in the isKenteken function?
You shouldn't create function that will reference to Vue component outside Vue application scope. Instead, You should place the isKenteken() function inside Vue component as following
<script>
import {Validator} from 'vee-validate';
import nl from 'vee-validate/dist/locale/nl';
Validator.localize('nl', nl);
Validator.extend('kenteken', {
validate:isKenteken,
getMessage: (field, params, data) => {
loader.kenteken = false;
voertuig.merk = data.message.Merk;
}
});
export default {
name: "app",
data() {
return {
voertuig: {
kenteken: '',
model: '',
model_id: '',
type: '',
type_id: '',
merk: '',
merk_id: '',
brandstof: '',
schadevrijejaren: ''
},
bestuurder: {
geboortedatum: '',
postcode: '',
huisnummer: '',
straat: '',
woonplaats: ''
},
loader: {
kenteken_onbekend: false,
kenteken: false,
},
}
},
methods{
isKenteken(value){
this.loader.kenteken= true;
return axios.post('/api/validate/kenteken', {kenteken: value}).then((response) => {
// Notice that we return an object containing both a valid property and a data property.
this.loader.kenteken = false;
this.voertuig.merk = response.data.Algemeen.Merk;
this.voertuig.model = response.data.Algemeen.Type;
this.voertuig.brandstof = response.data.Algemeen.Brandstof.toLowerCase();
this.voertuig.type_id = response.data.Algemeen.TypeId;
this.voertuig.model_id = response.data.Algemeen.ModelId;
this.voertuig.merk_id = response.data.Algemeen.MerkId;
console.log(response.data.Algemeen);
return {
valid: true,
data: {
message: response.data.Algemeen,
}
};
}, (error) => {
console.log(error);
this.voertuig.kenteken = '';
this.loader.kenteken_onbekend = 1;
this.loader.kenteken = false;
return false;
});
}
},
mounted() {
var self = this;
}
}
</script>
If you need to use the function from other component. You will need to find a way to make them reference to this component in order to use this methods. For example, inside other component's mounted(), you can use the root component methods by this.$root.isKenteken()
I know that there are solutions to how to use ngstorage in our applications to have persistent data available even after refresh. I tried implementing it for the first time in my form today. But unable to figure out where I am going wrong. Can someone please let me know where I am going wrong? Also, I am looking to have the persistent functionality on adding and deleting the data.
angular.module('myApp', ['ngStorage'])
.controller('AppController', ['$scope', '$localStorage',
'$sessionStorage',
function($scope,$localStorage,$sessionStorage) {
var self = this;
self.$storage = $localStorage;
self.user = {
id: null,
username: '',
address: '',
email: ''
};
self.id = 4;
self.users = [{
id: 1,
email: 'sam#tarly.com',
firstname: 'Sam',
lastname: 'Tarly',
telephone: 1234567890,
address: 'NY',
}, {
id: 2,
email: 'jon#snow.com',
firstname: 'Jon',
lastname: 'Snow',
telephone: 9876543210,
address: 'The Wall',
}, {
id: 3,
email: 'dany#targaryen.com',
firstname: 'Dany',
lastname: 'Targaryen',
telephone: 1234987650,
address: 'NEBRASKA'
}];
self.submit = function() {
if (self.user.id === null) {
self.user.id = self.id++;
alert('Added New User', self.user);
self.users.push(self.user);
$localStorage.users = self.users;
} else {
for (var i = 0; i < self.users.length; i++) {
if (self.users[i].id === self.user.id) {
self.users[i] = self.user;
break;
}
}
alert('User updated with id ', self.user.id);
}
self.reset();
};
self.edit = function(id) {
alert('id to be edited', id);
for (var i = 0; i < self.users.length; i++) {
if (self.users[i].id === id) {
self.user = angular.copy(self.users[i]);
break;
}
}
};
self.remove = function(id) {
alert('id to be deleted', id);
for (var i = 0; i < self.users.length; i++) {
if (self.users[i].id === id) {
self.users.splice(i, 1);
$localStorage.users = self.users;
if (self.user.id === id) { //It is shown in form, reset it.
self.reset();
}
break;
}
}
};
self.reset = function() {
self.user = {
id: null,
username: '',
address: '',
email: ''
};
$scope.myForm.$setPristine(); //reset Form
};
}
]);
Plnkr Link
From my understanding, for you the issue is the value not shown in table after adding the data and refreshing the page. The problem is you are initially loading the data with static array value. The data is infact added to storage. You just have to call the initial loading from $localStorage. Just change the self.users = [{..}] to self.users = $localStorage.users. I have updated the plunkr. Please take a look at it.
Plunkr
Trying to set creditCardExpMonth to the current month in the below Magento 2 JavaScript class (cc-form.js). The option month values are 1-12. When I manually add a month value like 3 creditCardExpMonth: 3, to the defaults:{ }, it works as expected. I just can't seem to figure out how to set it to the current month dynamically. I'm open to any solution that allows for the value to be overridden by the user's selection but I'd prefer it be inside this class or on the html page and not a JQuery update after the page loads.
I created a getCurrentMonth() function in this class but couldn't figure out how to access it correctly to set creditCardExpMonth to a default value.
define(
[
'underscore',
'Mageplaza_Osc/js/view/payment/default',
'Magento_Payment/js/model/credit-card-validation/credit-card-data',
'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator',
'mage/translate'
],
function (_, Component, creditCardData, cardNumberValidator, $t) {
return Component.extend({
defaults: {
creditCardType: '',
creditCardExpYear: '',
creditCardExpMonth: '',
creditCardNumber: '',
creditCardSsStartMonth: '',
creditCardSsStartYear: '',
creditCardVerificationNumber: '',
selectedCardType: null
},
initObservable: function () {
this._super()
.observe([
'creditCardType',
'creditCardExpYear',
'creditCardExpMonth',
'creditCardNumber',
'creditCardVerificationNumber',
'creditCardSsStartMonth',
'creditCardSsStartYear',
'selectedCardType'
]);
return this;
},
initialize: function() {
var self = this;
this._super();
//Set credit card number to credit card data object
this.creditCardNumber.subscribe(function(value) {
var result;
self.selectedCardType(null);
if (value == '' || value == null) {
return false;
}
result = cardNumberValidator(value);
if (!result.isPotentiallyValid && !result.isValid) {
return false;
}
if (result.card !== null) {
self.selectedCardType(result.card.type);
creditCardData.creditCard = result.card;
}
if (result.isValid) {
creditCardData.creditCardNumber = value;
self.creditCardType(result.card.type);
}
});
//Set expiration year to credit card data object
this.creditCardExpYear.subscribe(function(value) {
creditCardData.expirationYear = value;
});
//Set expiration month to credit card data object
this.creditCardExpMonth.subscribe(function(value) {
creditCardData.expirationYear = value;
});
//Set cvv code to credit card data object
this.creditCardVerificationNumber.subscribe(function(value) {
creditCardData.cvvCode = value;
});
},
getCode: function() {
return 'cc';
},
getData: function() {
return {
'method': this.item.method,
'additional_data': {
'cc_cid': this.creditCardVerificationNumber(),
'cc_ss_start_month': this.creditCardSsStartMonth(),
'cc_ss_start_year': this.creditCardSsStartYear(),
'cc_type': this.creditCardType(),
'cc_exp_year': this.creditCardExpYear(),
'cc_exp_month': this.creditCardExpMonth(),
'cc_number': this.creditCardNumber()
}
};
},
getCcAvailableTypes: function() {
return window.checkoutConfig.payment.ccform.availableTypes[this.getCode()];
},
getIcons: function (type) {
return window.checkoutConfig.payment.ccform.icons.hasOwnProperty(type)
? window.checkoutConfig.payment.ccform.icons[type]
: false
},
getCcMonths: function() {
return window.checkoutConfig.payment.ccform.months[this.getCode()];
},
getCcYears: function() {
return window.checkoutConfig.payment.ccform.years[this.getCode()];
},
hasVerification: function() {
return window.checkoutConfig.payment.ccform.hasVerification[this.getCode()];
},
hasSsCardType: function() {
return window.checkoutConfig.payment.ccform.hasSsCardType[this.getCode()];
},
getCvvImageUrl: function() {
return window.checkoutConfig.payment.ccform.cvvImageUrl[this.getCode()];
},
getCvvImageHtml: function() {
return '<img src="' + this.getCvvImageUrl()
+ '" alt="' + $t('Card Verification Number Visual Reference')
+ '" title="' + $t('Card Verification Number Visual Reference')
+ '" />';
},
getSsStartYears: function() {
return window.checkoutConfig.payment.ccform.ssStartYears[this.getCode()];
},
getCcAvailableTypesValues: function() {
return _.map(this.getCcAvailableTypes(), function(value, key) {
return {
'value': key,
'type': value
}
});
},
getCcMonthsValues: function() {
return _.map(this.getCcMonths(), function(value, key) {
return {
'value': key,
'month': value.substring(0,2)
}
});
},
getCcYearsValues: function() {
return _.map(this.getCcYears(), function(value, key) {
return {
'value': key,
'year': value
}
});
},
getCurrentMonth: function() {
var d = new Date();
var n = d.getMonth() + 1;
return n;
},
getCurrentYear: function() {
var d = new Date();
var n = d.getYear();
return n;
},
getSsStartYearsValues: function() {
return _.map(this.getSsStartYears(), function(value, key) {
return {
'value': key,
'year': value
}
});
},
isShowLegend: function() {
return false;
},
getCcTypeTitleByCode: function(code) {
var title = '';
_.each(this.getCcAvailableTypesValues(), function (value) {
if (value['value'] == code) {
title = value['type'];
}
});
return title;
},
formatDisplayCcNumber: function(number) {
return 'xxxx-' + number.substr(-4);
},
getInfo: function() {
return [
{'name': 'Credit Card Type', value: this.getCcTypeTitleByCode(this.creditCardType())},
{'name': 'Credit Card Number', value: this.formatDisplayCcNumber(this.creditCardNumber())}
];
}
});
});
Here is the knockout HTML with select data-bind just in case it's needed (taken from Magento payment cc-form.html):
<select name="payment[cc_exp_month]"
class="select select-month"
data-bind="attr: {id: getCode() + '_expiration', 'data-container': getCode() + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
enable: isActive($parents),
options: getCcMonthsValues(),
optionsValue: 'value',
optionsText: 'month',
optionsCaption: $t('Month'),
value: creditCardExpMonth">
</select>
If this script is run every time the page loads, you could do something like this:
defaults: {
creditCardType: '',
creditCardExpYear: '',
creditCardExpMonth: (function(){
return ((new Date()).getMonth()+1);
})(),
creditCardNumber: '',
creditCardSsStartMonth: '',
creditCardSsStartYear: '',
creditCardVerificationNumber: '',
selectedCardType: null
}
or if you want something cleaner, you can refactor the code into a function that is defined prior to this object creation:
function (_, Component, creditCardData, cardNumberValidator, $t) {
function getCurrentMonth() {
return ((new Date()).getMonth()+1);
}
return Component.extend({
defaults: {
creditCardType: '',
creditCardExpYear: '',
creditCardExpMonth: getCurrentMonth(),
creditCardNumber: '',
creditCardSsStartMonth: '',
creditCardSsStartYear: '',
creditCardVerificationNumber: '',
selectedCardType: null
},
I have experience in writing statics functions in moongose like
var mongoose =require('mongoose');
var Schema = mongoose.Schema;
var adminSchema = new Schema({
fullname : String,
number : Number,
email: String,
auth : {
username: String,
password : String,
salt: String
}
});
adminSchema.statics.usernameInUse = function (username, callback) {
this.findOne({ 'auth.username' : username }, function (err, doc) {
if (err) callback(err);
else if (doc) callback(null, true);
else callback(null, false);
});
};
here usernameInUse is the function I wana write but using sequelize for mysql database
my model
/*
This module is attendant_user table model.
It will store attendants accounts details.
*/
"use strict";
module.exports = function(sequelize, DataTypes) {
var AttendantUser = sequelize.define('AttendantUser', {
username : {
type : DataTypes.STRING,
allowNull : false,
validate : {
isAlpha : true
}
},{
freezeTableName : true,
paranoid : true
});
return AttendantUser;
};
How to add statics function here..??
Well, you can easily use Expansion of models
var User = sequelize.define('user', { firstname: Sequelize.STRING });
// Adding a class level method
User.classLevelMethod = function() {
return 'foo';
};
// Adding an instance level method
User.prototype.instanceLevelMethod = function() {
return 'bar';
};
OR in some cases you may use getter and setter on your models. See the docs:
A) Defining as part of a property:
var Employee = sequelize.define('employee', {
name: {
type : Sequelize.STRING,
allowNull: false,
get : function() {
var title = this.getDataValue('title');
// 'this' allows you to access attributes of the instance
return this.getDataValue('name') + ' (' + title + ')';
},
},
title: {
type : Sequelize.STRING,
allowNull: false,
set : function(val) {
this.setDataValue('title', val.toUpperCase());
}
}
});
Employee
.create({ name: 'John Doe', title: 'senior engineer' })
.then(function(employee) {
console.log(employee.get('name')); // John Doe (SENIOR ENGINEER)
console.log(employee.get('title')); // SENIOR ENGINEER
})
B) Defining as part of the model:
var Foo = sequelize.define('foo', {
firstname: Sequelize.STRING,
lastname: Sequelize.STRING
}, {
getterMethods : {
fullName : function() { return this.firstname + ' ' + this.lastname }
},
setterMethods : {
fullName : function(value) {
var names = value.split(' ');
this.setDataValue('firstname', names.slice(0, -1).join(' '));
this.setDataValue('lastname', names.slice(-1).join(' '));
},
}
});
Hope it helps.
AttendantUser.usernameInUse = function (username, callback) {
...
};
return AttendantUser;