Passing data property as function argument in vue.js - javascript

Instead of having few methods that look like:
showDiv1(){
this.showDiv1 = true
},
showDiv2(){
this.showDiv2 = true
}
I am trying to create one like:
showElements(...elementNames){
elementNames.forEach(name => {
this.$data.name = true
})
}
The idea was to pass one or few properties from data and when calling the method those elements would should up on screen.
In data I have something like this:
data() {
return {
div1 = false,
div2 = false
}
}
In html I tried to call the function on click in a couple of ways:
<button #click="showElements('div1')">Show<button>
<button #click="showElements(div1)">Show<button>
<div v-if="div1">
<p>Hello</p>
</div>
But nothing happens.

Seems like you have a syntax error. Instead of writing to your data object like this:
data() {
return {
div1 = false,
div2 = false
}
}
You should write it like this:
data() {
return {
div1: false,
div2: false
}
}
Make sure to only use syntax that fits an object in the data object. Then, you can call it like this:
<button #click="showElements(div1)">Show<button>
One more thing, when accessing the data you don't actually need to write $data. Simply write 'this.name' in order to access your data.

Dynamic property names are supposed to be accessed with bracket notation:
showElements(...elementNames){
elementNames.forEach(name => {
this[name] = true
})
}
The method is supposed to be used like:
<button #click="showElements('div1')">Show<button>

Related

The html is not shown based on locally saved variables

I have a component that needs to display html based on a boolean variable. I make this variable the same as the one I set in the localStorage.
So if I click on foo, I set it to false both as a variable and in the localStorage. If I click on the bar I set it to true.
Now, before loading the component I'm going to get this variable, and I make it the same as the one I have locally, so if I clicked on foo, when I reload the component, the variable is false, and therefore the html should show me foo. but I don't understand why he shows me bars!!!
It's a bit complicated to explain I hope you understand from the code:
<template>
<div id="app">
<h2 v-if="!isTrue">FOO</h2>
<h2 v-else>BAR</h2>
<button #click="foo()">FOO</button>
<button #click="bar()">BAR</button>
</div>
</template>
<script>
export default {
name: 'App',
data: function () {
return {
isTrue: null,
};
},
created() {
const boh = localStorage.getItem('boh');
this.isTrue = boh;
console.log('boh', boh);
console.log('isTrue', this.isTrue);
},
methods: {
foo() {
this.isTrue = false;
localStorage.setItem('boh', false);
},
bar() {
this.isTrue = true;
localStorage.setItem('boh', true);
},
},
};
</script>
I am attaching an example on stackblitz so maybe you can do tests:
https://stackblitz.com/edit/vue-b3ieft?file=src%2FApp.vue
Because a variable you saved in the localStorage is a string. When you do:
const boh = localStorage.getItem('boh');
this.isTrue = boh;
Actually you get:
this.isTrue = 'true';
And this string is always true.
To avoid this you could check if it is true string:
const boh = localStorage.getItem('boh');
this.isTrue = boh === 'true';
https://stackblitz.com/edit/vue-mnuhbr?file=src%2FApp.vue
Adding on to #Georgy's answer. To escape an unnecessary check, it is a good practice for booleans to be stringified while setting the localstorage, and parsed when getting the item.
Setting
localStorage.setItem("boh", JSON.stringify(false));
Getting
const boh = JSON.parse(localStorage.getItem('boh'))

Return answer of inquirer prompt inside of another function

I have a function wherein I want to do some things with a class object selected by the user. I was thinking, I present them with some options, then after they select it, I use the string to identify the class object in an array of objects like so:
function askAboutIt() {
var questions = [{
type: 'list',
name: 'theList',
message: "Message",
choices: listArray
}]
inquirer.prompt(questions).then(answers => {
var itemInQuestion = (answers['theList']);
function isPicked(item) {
return item.name === itemInQuestion;
}
var picked = (listArray.find(isPicked));
})
}
Basically inside of some other function I would like to be able to call askAboutIt() and have it return picked. That way I could, for example, console.log(askAboutIt()), or maybe create a variable equal to askAboutIt().someOtherPropertyofmyListArrayClass.
I tried sticking a return in my inquirer function, but it returns as undefined, so then I thought, maybe I could stick an await outside of my console.log, but that's not getting the return either.
So then I tried using the when method from this answer, but then I got returned an error that "when is an unexpected identifier." Where exactly am I supposed to put the when method, or should I use something else entirely?
I figured it out! I was able to do it by inverting my strategy. Instead of calling askAboutIt() in another function, I wrote another function parentFunction(answer) and gave it the parameter answer.
Then, inside askAboutIt, I called that function, like this:
function askAboutIt() {
var questions = [{
type: 'list',
name: 'theList',
message: "Message",
choices: listArray
}]
inquirer.prompt(questions).then(answers => {
var itemInQuestion = (answers['theList']);
function isPicked(item) {
return item.name === itemInQuestion;
}
var picked = (listArray.find(isPicked));
parentFunction(picked);
})
}
In this way, I can use the answer of this question in another function.

Vue.js - How to pass parameters to a JavaScript filter function within a computed property?

I want to pass a variable as a parameter to a computed property.
computed: {
dishes() {
let param = this.cuisine;
let dishes = this.restaurant.restaurant_items.filter(element => {
element.param
});
return dishes;
}
},
data(){
return{
cuisine:""
}
}
Here as the param I pass a value which is an element of restaurant_items array's objects.
eg(:- is_thai)
But this doesn't output me anything. What's wrong with my code?
Computed properties don't accept parameters. But you can use a method to accomplish the same thing
methods: {
dishes(param) {
// return whatever
}
}
If I understand you correctly what you actually want to do is:
computed: {
dishes() {
return this.restaurant.restaurant_items.filter((e) => e[this.cuisine])
}
}
You need to use bracket notation to access object properties via a variable, not dot notation.

Pass a variable by reference from Angular2 template

Let's say I have a variable called isVisible. And I have a method called
ReverseVariable(variable: boolean)
{
variable = !variable;
}
I want to call this method from a template like
<button (click)="ReverseVariable(isVisible)"></button>
I want to give it isVisible in the parameters and have isVisible reverse itself. Something like the following example is not an option
ReverseVisibility()
{
this.isVisible = !this.isVisible;
}
Is there any way that I can pass the variable by reference?
Not with a primitive data type like a boolean. What you could do is make a non-primitive like an object
isVisible = {
flag: true
}
Then toggle that in your function
ReverseVisibility(isVisible)
{
isVisible.flag = !isVisible.flag;
}
Here is plnkr demonstrating this (https://plnkr.co/edit/VYEimNoHZvGxeE4S2W4L?p=preview)

Polymer- use behavior to share object between elements?

Is it possible to use behaviors to share a object between elements?
<script>
selectedBehavior = {
properties: {
selected: Object
}
}
</script>
<dom-module id="paper-menu-custom">
<style>
</style>
<template>
<paper-menu attr-for-selected="name" selected="{{selected.choice}}">
...
<script>
Polymer({
is: "paper-menu-custom",
behaviors: [selectedBehavior]
});
toolbars = document.querySelector('paper-menu-custom');
toolbars.selected.choice = "home";
Uncaught TypeError: Cannot set property 'choice' of undefined
You do not need to use a behavior to share information between elements.
You should use IronMeta like so :
Declaratively and with data-binding :
<iron-meta key="my-unique-key" value="{{mySharedInformation}}"></iron-meta>
Then use mySharedInformation the same way you would any custom element's properties. Setting it will update the value of any other <iron-meta> in your code that shares the same key.
In plain javascript :
Read
var mySharedInformation = new Polymer.IronMeta().byKey('my-unique-key');
Write
new Polymer.IronMeta({key: 'my-unique-key', value: mySharedInformation});
Take a look at my object in github (https://github.com/akc42/akc-meta), it allows one element to publish a value with a key, and other ti have multiple instances subscribe to it and get the data out again.
It does it by keeping instances in a private variable
(function(){
var private;
Polymer({element definition has access to private});
})();
I got it with this:
<script>
selectedBehavior = {
properties: {
selected: {
type: Object,
value: function() { return { choice: 'home'} }
}
}
}
</script>
It seems specifying a object is not enough. I need to return a object for the value of object. Doesn't make alot of sense because in documentation I should just be able to say foo: Object. But, maybe this is a special case sense I am using it as a behavior.
Unfortunately, two elements can not share the same obj.property through behaviors. Each will have it's own instance.
If you want to share an object between the different instances of your element, you have to avoid using a function as describe in the Documentation
So this should be working as you expect:
<script>
selectedBehavior = {
properties: {
selected: {
type: Object,
value: { choice: 'home'} }
}
}
}
</script>

Categories