Vue: My initial data value is not accessible when used as a function param - vue.js

I am having an issue when triggering the click handler in my button here. The error comes back as TypeError: Cannot read property 'discountProduct' of null when I click the button. I know for a fact that this.discountProduct.id has a value by inspecting it from the Vue Tools and by knowing that the button is rendering to begin with since it only conditionally shows if the id > 1.
I alternatively tried to remove this but it still throws the same error.
I also tried manually just inserting the product id as the param and that works so I am not sure what the issue is at this point.
<button v-if="this.discountProduct.id >= 1"
type="button"
v-on:click="addToCart(this.discountProduct.id, true)"

Is you button in the <template> tags?
If so, you do not need to use this delete from the click argument and v-if. However that should only throw a warning.
Can you also post the code for the method addToCart?
If you are not setting the full discountProduct object you will need to make sure setting the id is reactive. Like the example below:
this.$set(this.discountProduct, 'id', 1)
Nested Object/keys are not reactive without using $set. See https://v2.vuejs.org/v2/guide/reactivity.html for more details.
Hope this helps

Related

"v-on with no argument expects an object value" facing this error in quasar selector when focus into the field

here is my code, options array updated in created hook based on api response and response of api is array of object and v-model value is also updated in created hook. this selector is of input type and also filter the data based on input type from options array.
hope so this chunk of code is enough to explain.
<q-select
ref="registeredCountry"
for="registeredCountry"
color="olab-brand-blue"
v-model="registeredAddress.country"
use-input
fill-input
hide-selected
:options="countryOptions"
#filter="filterCountryList"
emit-value
option-label="countryName"
option-value="countryName"
#update:model-value="resetStateAndCityFields('registeredAddress')"
map-options
>
</q-select>
I got exactly the same Vue warning with one of my q-selects, after migrating it (unchanged) from Vue 2/Quasar 1 to Vue 3/Quasar 2. The same q-select code worked without warnings on the older levels. The warning is very unspecific from a Quasar point of view.
However, I found a hint on https://github.com/quasarframework/quasar/issues/8898 to eliminate this warning, which helped to resolve the issue in my case.
The reason for the warning was in my case due to the use of q-chips with q-items for the options in the q-select. Those q-items for the q-select options used "v-on='scope.itemEvents'", together with "v-bind='scope.itemProps'", which was the recommended combination in Quasar 1/Vue 2.
In Quasar 2/Vue 3 the "v-on='scope.itemEvents' is no longer necessary (if used, it causes this Vue warning). Just search for all "v-on='scope.itemEvents'" in your template code, then drop (i.e. delete) those "v-on=...", but keep the "v-bind=...".
This eliminates the above Vue warnings (which otherwise come up for every selectable option in your q-select).

How to auto-close date popup and hide div on selected change of element?

Rent Date doesn't auto close. It’s getting error as below. I'm not sure it's inside of the Div. Getting below error.
"[Vue warn]: Error in v-on handler: 'TypeError: $refs.qDateProxy.hide is not a function'
Want to hide the RentDate when user select Buy from individual Book’s Select Option. How should I change it? There will be multiple books.
Codepen
To auto close the date popup when user select on the date.
Hide 'RentDate' when user choose
You could use v-if or v-show for conditional hide show the Book RentDate on changes of boot type.
The directive v-if is used to conditionally render a block. The block will only be rendered if the directive’s expression returns a truthy value.
<h1 v-if="awesome">Vue is awesome!</h1>
Another option for conditionally displaying an element is the v-show directive. The usage is largely the same:
<h1 v-show="ok">Hello!</h1>
And for this error $refs.qDateProxy.hide, you can create a method and inside of this method you can use like below
onRentDateChange(){
this.$refs.qDateProxy[0].hide()
},
You can check here with working codepen.io.
EDIT
As per OP's comment, I have updated codepen.io. I have taken boolean variable inside of this.$data.Books array and used .find() method of array for changing variable status.
onValueChange(val,id){
let rec = this.$data.Books.find(({ID})=> ID==id);
if(rec) rec.isRentShow = val == 'Rent';
},

How can I pass an index variable from Angular 5's ngFor to a component method?

I have a list of images that I'm looping over and displaying in the browser. Each image has a click handler which only accepts one argument - the image's index. The problem is, I can't quite figure out how to pass that index to the method.
<img *ngFor="let img of images; let i = index"src="{{img}}" alt="{{i}}"
(click)="doSomething({{i}})">
I'd like to be able to pass that 'i' into the doSomething() method but I can't quite figure out how to without getting an error. Help.
Just remove the template braces - the (click) event callback is just plain JS so you can call:
(click)='doSomething(i)'

Vue.js get element by id/ref

I have a custom component called 'menu-entry':
<menu-entry v-for="field in fields" :id:"field.id" :ref="field.id" v-bind:key="field.id" v-bind:class="[classArray]" v-bind:field="field" v-on:clicked="menuEntryClicked">
</menu-entry>
I need to get one of them (for example field.id = 2) and remove an item from the classArray.
this.$refs[2] is working for HTML elements, but not for custom elements.
this.$el.querySelector isnt working either.
is there another way to remove an item from the classArray of a specific element?
Your question it is not clear but you are trying to set id and ref to field.id so following this logic it is not necessary to do though.
You can just send the id to the method you are executing like below:
<menu-entry
v-for="field in fields"
v-bind:key="field.id"
v-bind:class="[classArray]"
v-bind:field="field"
v-on:clicked="menuEntryClicked(field.id)" // <= send the id here
>
</menu-entry>
I am not sure if i helped but regarding your question, now you can figoure out which id of element is clicked and remove it from classArray or whatever you want
2 is not a valid id selector when you use document.querySelector('#2'); maybe you can use document.getElementById('2') instead - it can work.

Issue with vue.js conditional rending

I have problem in rendering a template
When a new data has been added, it won't go to the process of v-if even if the condition is both TRUE.
Can some please explain why?
I have provided some screenshot below to explain further my issue
This first image was my template for displaying the products, you will notice the add, update and remove in here.
The second image shows that I'm trying to add a new product
The third image shows that I have successfully added the new product. The problem is, the action button "update" is triggered but won't take any effect.
The image above shows that the update button works with the past data, but not with the new one.
This last image will prove that the button has been triggered. I've added a console.log to display the following upon clicking the update button.
INDEX of the row, which is [0].
The typeOf the variable 'isUpdate' [boolean].
The value of 'isUpdate' [True, False]
and the productID which is [151]
Any idea why it hasn't been triggered, or any idea how to debugged this?
If you want to see the code. I can provide it, just tell me which part are you looking for. As I don't have any idea which part has the error.
Thank you in advance.
Updated
AS per Amresh Venugopal Request
Here is the v-if in the template
<tr v-if='product.id > 0 && product.isUpdate' class='table-inputs'>
And the updatebtn function
canUpdate: function(data) {
console.log(data.pindex);
this.products[data.pindex].isUpdate = !this.products[data.pindex].isUpdate;
console.log(typeof this.products[data.pindex].isUpdate);
console.log(this.products[data.pindex].isUpdate);
console.log(this.products[data.pindex].id);
}
I only set the isUpdate value to 'true' if 'false', and viceversa.
The productID is added after the ajax save function.
I figure it out!
When I push the data in this.products, I didn't include the 'isUpdate' field.
Got it working now.