Bootstrap Vue datepicker failed for prop max, expected String, Date, got Date - vue.js

I am using Bootstrap Vue and more specifally the formdatepicker.
It's looking like this:
<b-form-datepicker
v-model="user.birthdate"
class="mb-2"
:max="maxBirthdate"
:placeholder="$t('birthdate_field_placeholder')"
:show-decade-nav="true"
/>
I want to restrict the max date to be 16 years ago from today.
So I use this code:
created () {
let now = new Date()
let today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
let todayMinusSixteenYears = new Date(today)
todayMinusSixteenYears.setFullYear(todayMinusSixteenYears.getFullYear() - 16)
this.maxBirthdate = todayMinusSixteenYears
},
When I then start my Nuxt app, I am getting the following error:
[Vue warn]: Invalid prop: type check failed for prop "max". Expected String, Date, got Date
found in
---> <BCalendar>
<BVFormBtnLabelControl>
<BFormDatepicker>
<Anonymous>
<BFormGroup>
<FormControlWrapper> at components/form/FormControlWrapper.vue
<ValidationObserver>
<Pages/register/volunteer.vue> at pages/register/volunteer.vue
<Nuxt>
<Layouts/default.vue> at layouts/default.vue
<Root>
I'm not sure where or what the error is, since the variable is definitely a Javascript Date.
When trying to put .toString() at the end, it does not work at all anymore.
Please note, that even though the application is giving the error as shown, it does work perfectly with the Javascript Date object.

Without the full script (especially the data object) I can't say what is the root of your issue here, but going off of the Bootstrap Vue demo, the code below works. What you're likely experiencing is a conflict between created function and whatever you have in data
<script>
export default {
data() {
let now = new Date()
let today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
let todayMinusSixteenYears = new Date(today)
todayMinusSixteenYears.setFullYear(todayMinusSixteenYears.getFullYear() - 16)
return {
value: '',
maxBirthdate: todayMinusSixteenYears,
}
}
}
</script>

Related

Stuck with $ref pointing to Proxy object with vue-router

I was using VueJS in browser mode and am now trying to switch my code to a VueJS SPA and vue-router. I've been stuck for hours with a $refs not working anymore.
To interact with my Google Charts, I was using an absolute reference to the graph (this.$refs.villesChart) to get selected data like that:
computed: {
eventsprox() {
let eventsprox = {
select: () => {
var selection = "";
if (this.$refs.villesChart) selection = this.$refs.villesChart1.chartObject.getSelection();
if (selection.length) {
var row = selection0[0].row + 1;
this.code_commune = this.dataprox[row][4];
this.changerville(this.code_commune, this.dataprox[row][0]);
}
return false;
},
};
return eventsprox;
}
HTML code for graph:
<GChart type="BarChart" id="villesChart" ref="villesChart" :data="dataprox" :options="optionsprox" :events="eventsprox"/>
I don't know why, but in browser mode, this.$refs.villesChart is a component:
[1]: https://i.stack.imgur.com/xJ8pV.png
but now it is a proxy object, and lost its chartObject attribute:
[2]: https://i.stack.imgur.com/JyXrL.png
I'm really confused. Do you have an idea why?
And if I use the proxy object, then I get a Vue warning "Avoid app logic that relies on enumerating keys on a component instance" and it is not working in production environment.
Thanks a lot for your help!!
After hours of testing different solutions, I finally found a solution working with Vue3 and Vue-google-chart 1.1.0.
I got rid of "refs" and put the events definition and code in the data section of my Vue 3 app (instead of computed) and accessed the chart data through a component variable I used to populate it.
Here is my event code where this.dataprox is my data table for the chart:
eventsprox: {
'click': (e) => {
const barselect = parseInt(e.targetID.split('#')[2]) + 1;
this.code_commune = this.dataprox[barselect][4];
this.nom_commune = this.dataprox[barselect][0];
this.changerville(this.code_commune, this.nom_commune);
}
},
My Gchart html code:
<GChart type="AreaChart" :data="datag" :options="optionsg" :events="eventsprox"/>
I hope it can help!

dueChange event for duet picker not working with Ionic 5 / Vue 3

I am using Duet Date Picker in the Ionic 5/ Vue 3 application. The event listener for the duetChange is not working for me.
Here is my code snippet:
<duet-date-picker #duetChange="handleInput($event)"identifier="date" :localization.prop="localisation" direction="left"></duet-date-picker>
handleInput(e: any) {
console.log("e", e);
this.$emit("input", this.content);
}
I have even tried following listners:
v-on:duetChange="handleInput($event)"
v-on:change="handleInput($event)"
#change="handleInput($event)"
Is this the right way to add an event listener or am I missing something?
Here is the code sandbox link:
https://codesandbox.io/s/old-silence-1f0nx?file=/src/App.vue
TIA
I tried to use the duetDatePicker in a Vue CodeSandbox, the following works:
<duet-date-picker
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>
Along with the above, my methods object contained the handleInput function declaration.
Check the App.vue file in the codesandbox for details.
I was able to get it to work the old fashion way...
onMounted(() => {
// Select the date picker component
const date = document.getElementById("date-picker");
// Listen for when date is selected
date.addEventListener("duetChange", function (e) {
console.log("selected date", e.detail.valueAsDate);
});
});
<duet-date-picker id="date-picker"
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>

What is the mechanism of calling a function from a template in Vue js

I am trying to learn Vue.js. I am following a tutorial on this site https://scrimba.com/p/pZ45Hz/c7anmTk. From here I am not getting something clear.
Here is the code below and my confusion as well :
<div id="app">
<wizard :name="harry" :cast="oculus_reparo" ></wizard>
<wizard :name="ron" :cast="wingardium_leviosa"></wizard>
<wizard :name="hermione" :cast="alohomora" ></wizard>
</div>
// emojify returns the corresponding emoji image
function emojify(name) {
var out = `<img src="emojis/` + name + `.png">`
return out
}
// cast returns a spell (function) that decorates the wizard
function cast(emoji) {
var magic = emojify("magic")
return function (wizard) {
return wizard + " " + magic + " " + emoji + " " + magic
}
}
Vue.component("wizard", {
props: ["name", "cast"],
template: `<p v-html="cast(name)"></p>`
})
var app = new Vue({
el: "#app",
data: {
harry : emojify("harry" ),
ron : emojify("ron" ),
hermione : emojify("hermione")
},
methods: {
// oculus_reparo returns a spell (function) that repairs glasses
oculus_reparo: cast(emojify("oculus-reparo")),
// wingardium_leviosa returns a spell (function) that levitates an object
wingardium_leviosa: cast(emojify("wingardium-leviosa")),
// alohomora returns a spell (function) that unlocks a door
alohomora: cast(emojify("alohomora"))
}
})
So far what I have got is that, I have created a component named wizard which takes two properties - name and cast. name is getting the value from data, and so far I understand that cast is calling the method with a parameter.
So both of them should return their specific image. My first confusion: Where does wizard come from and how is it showing the data.name image? If it is because of the method call in the template then why does emoji return another image?
I think the example is unnecessarily complex for the ideas you're looking to learn.
wizard is being globally registered with Vue by Vue.component("wizard", ...). When Vue interprets each wizard call in the template it will replace it with <p v-html="cast(name)"></p> which is set in the wizard component definition. Here name gets mapped to the property that is set via :name=. v-html is just saying to render as html the return value of cast(name), here cast is the function property that is passed to the component and not the cast function locally defined. Everything after that happens as you would expect where emojify returns a template literal that is passed to cast, that then returns a function, which combines the emoji and other properties.

Compile Vuejs element

I'm trying to use Vuejs with some plugins.
There are two components
Vue.component('element-one', {
template: '<h1>Element ONE</h1>',
}
And the second one :
Vue.component('element-two', {
template: '<h1>Element TWO</h1>',
}
I want to be able to display the compiled version of element-one in element-two, I know there is something like:
var element = Vue.component('element-one');
new element().$mount().$appendTo('body');
But I'd love to have just the 'mounted' version, and not append it to any place.
Something I can play with in console.log ??
I received an answer from https://gitter.im/vuejs/vue. You can get the element by
new element().$mount().$el

vue js returned value gives undefined error

i want to check the returned value of $http.get() but i get undefined value. Here is my vue js code:
var vm = new Vue({
el: '#permissionMgt',
data: {
permissionID: []
},
methods:{
fetchPermissionDetail: function (id) {
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
this.permissionID = data.permissionID; //permissionID is a data field of the database
alert(this.permissionID); //*****this alert is giving me undefined value
});
},
}
});
Can you tell me thats the problem here?.. btw $http.get() is properly fetching all the data.
You need to check what type is the data returned from the server. If #Raj's solution didn't resolve your issue then probably permissionID is not present in the data that is returned.
Do a colsole.log(data) and check whether data is an object or an array of objects.
Cheers!
Its a common js error. Make the following changes and it will work.
fetchPermissionDetail: function (id) {
var self = this; //add this line
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
self.permissionID = data.permissionID; //replace "this" with "self"
});
},
}
the reason is this points to window inside the anonymous function function()
This is a well known js problem. If you are using es2015 you can use arrow syntax (() => { /*code*/ }) syntax which sets this correctly