[Vue warn]: Property or method "Boston" is not defined on the instance but referenced during render - vue.js

I'm setting up some props, as shown below.
Component 1 (Parent):
<template>
<div>
<span>{{agency1}}</span>
<span>{{workstation}}</span>
</div>
</template>
<script>
export default {
name: "work-station-view",
props: {
agency1: {
type: String
},
workstation: {
type: Number
}
},
data() {
return {};
}
};
</script>
Component 2 (Child):
<template>
<WorkStationView :workstation="1.1" :agency1="Boston" />
</template>
The workstation prop renders fine, but the agency1 prop doesn't show up at all. I get this message from Vue in the console:
[Vue warn]: Property or method "Boston" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I checked the docs, as it says to define it in data(), so I did a combination of all of these (probably more) to no avail:
// attempt 1
data() {
agency1 = this.agency1;
return {};
}
// attempt 2
data() {
return {
agency1 = this.agency1;
};
}
// attempt 3
data() {
return {
agency1: '';
};
}
If I use a number value for agency1 (<WorkStationView :workstation="1.1" :agency1="3" />), it shows! What is going on?

If you're using an inline string, you should skip the : or quote your string.
The : is short-hand for v-bind and is expected to be used with variables that you're binding when passing attributes from the parent component to the child. In this case, you don't have a variable called Boston in the parent context, and hence the error from Vue.
If all you want to do is use a constant string like Boston, just use it like
<WorkstationView :workstation="1.1" :agency="'Boston'" />
Alternatively, it would've also worked if you did the following:
<WorkstationView :workstation="1.1" agency="Boston" />

:agency1="Boston" is shorthand for v-bind:agency1="Boston". It attempts to bind a data property named Boston, but you don't have one defined. :agency1="3" works because 3 is a literal. If you were attempting to assign the literal string "Boston" to agency1, don't use the preceding colon:
<!--
<WorkStationView :agency1="Boston">
--> <!-- DON'T DO THIS -->
<WorkStationView agency1="Boston">

Related

Vue Warn: Property or method is not defined on the instance but referenced during render

I have a model name defined in my Component tag as seen below:
<b-table-column v-if="" field="columnName" v-slot="itemProps">
<SelectableAttribute
:attr-name="props2.row.fieldClass"
:attr-id="itemProps.row.id"
:model-id="props.row.id"
:model-name="NewParticipant"
>
However I receive this error:
[Vue warn]: Property or method "NewParticipant" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
I'm not quite sure how I'm meant to define a model-name, in my props I assume but where? I've attached code below.
export default {
props: {
participants:
{
type: Array,
default: null
},
},
components: {
SelectableAttribute
},
As your error tells you, NewParticipant is not defined. You need to add it to your component as a property in data(), like this:
data() {
return {
NewParticipant: [] // Array for example
}
}
Or else, if you want your prop participants to be the model-name, you need to change it to :model-name="participants".

Vuejs - - Assigning prop value in child after ajax request in parent.

I am sure I am missing something simple here. I have created a reusable child component that includes a input like the following, and I am assigning the initialValue in the data object from the itemValue prop passed to it from the parent.
<template>
<label>{{itemLabel}}</label>
<input v-model="initialValue" type="text" >
</template>
<script>
export default {
props: ['itemValue'],
data(){
return {
initialValue: this.itemValue,
}
}
</script>
If in the parent component I assign the item-value property directly with a string it works fine.
The problem is I want to set the item-value after making an ajax call in the parent, so I am binding it to a data object property that is set by a method using beforeMount()
<v-child-component :item-value="theValue"></v-child-component>
And...
data(){
return {
theValue: null,
}
},
methods: {
setvalue(){
//make ajax axios get request here then set this.theValue
}
}
beforeMount(){
this.setValue();
}
When I do it this way the it seems the child's item-value is bound to the null value before ajax call completes and sets the actual value. How can I achieve my purpose here?
If you don't want the component to render until theValue is set, use the v-if directive:
<v-child-component v-if="theValue !== null" :item-value="theValue"></v-child-component>

computed nested property Vuejs

I have a problem with a modal component for computed nested property.
I have a parent component that calls "Modal component" passing data by props.
The object that I pass to my compoments is Like this:
modalProposal:{
name:test,
old: { name: oldTest }
}
So i pass my object to my components:
<modal :modal-proposal="modalProposal"></modal>
So my component modal should have:
export default {
props:["modalProposal"],
data() {
return {
}
},
computed:{
proposal(){
return this.modalProposal;
}
}
}
modalProposal is setted by function from component parent in v-for like:
<button class="btn btn-primary" id="show-modal" v-on:click="openModal(proposal)">see proposal</button>
function openModal:
openModal(proposal){
this.modalProposal = proposal;
$('#proposalModal').modal('show');
}
Now my problem is that, In template, If i write proposal.name It works but if I write proposal.old.name It returns error
"TypeError: Cannot read property 'name' of undefined"
How can I access to a nested property passed to proposal?
If, at any time, modalProposal.old is undefined then the code proposal.old.name will throw an error. Typically this is resolved by using a guard, or just not attempting to access proposal.old.name until proposal.old has a value.
Here is an example of a guard.
proposal.old && proposal.old.name

Vuejs component props as string

I want to pass this prop as a string:
<list-view :avatar="pictures"></list-view>
But I think Vue thinks I am trying to call a method because I am getting these warnings:
[Vue warn]: Property or method "pictures" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
[Vue warn]: Invalid prop: type check failed for prop "avatar". Expected String, got Undefined.
How can I pass "pictures" as a string?
Vue.component('list-view', {
props: {
avatar: { type: String, required: true },
},
template: `<div>{{ avatar }}</div>`,
});
var app = new Vue({ el: '#app' });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<list-view :avatar="pictures" ></list-view>
</div>
Right now, Vue is trying to find a variable named pictures to pass as the property value to the child component.
If you want to specify a string value in that inline expression, you can wrap the value in quotes to make it a string:
<list-view :avatar="'pictures'"></list-view>
Alternately, as #Zunnii answered below, if the value being passed is really just a static string, you can simply omit the v-bind colon shorthand:
<list-view avatar="pictures"></list-view>
This way, the avatar prop of the child component will be assigned the string value "pictures".
If you really want to pass static string, you can just pass string directly without v-bind
<div id="app">
<greeting text="world"></greeting>
</div>
then in JS file
Vue.component('greeting', {
props: ['text'],
template: '<h1>Hello {{ text }}!</h1>'
});
var vm = new Vue({
el: '#app'
});
JSFiddle => https://jsfiddle.net/dpLp4jk8/
:avatar="pictures" //vue treat pictures as a variable or computed properties
By default vue treat pictures as a variable or computed properties and vue search locally and doesn't find and throw an error. So what you have to do is tell vue externally that it is a string not a variable or computed properties. So enclose in quotes.
:avatar="'pictures'" // I guess it will work
In laravel we can pass string as shown below
function authUserCurrency(){
return '$';
}
<service :authusercurrency="'{!!authUserCurrency()!!}'"></services>
Vue.js Template
props:{authusercurrency:String},
OR
props:['authUserCurrency'],
In my case I needed to pass static string along with dynamic property value.
So did as below.
<home-card :title="'By' + post.author.name "></home-card>

Binding method result to v-model with Vue.js

How do you bind a method result to a v-model with Vue.js?
example :
<someTag v-model="method_name(data_attribute)"></someTag>
I can't make it work for some reason.
Thank you.
Years later, with more experience, I found out that is it easier to bind :value instead of using v-model. Then you can handle the update by catching #change.
Edit (per request):
<input :value="myValue" #change="updateMyValue">
...
methods: {
updateMyValue (event) {
myValue = event.target.value.trim() // Formatting example
}
}
And in a child component:
// ChildComponent.vue
<template>
<button
v-for="i in [1,2,3]">
#click="$emit('change', i) />
</template>
// ParentComponent.vue
<template>
<child-component #change="updateMyValue" />
</template>
<script>
import ChildComponent from './child-component'
export default {
components: {
ChildComponent
},
data () {
return {
myvalue: 0
}
},
methods: {
updateMyValue (newValue) {
this.myvalue = newValue
}
}
}
</script>
v-model expressions must have a get and set function. For most variables this is pretty straight forward but you can also use a computed property to define them yourself like so:
data:function(){
return { value: 5 }
},
computed: {
doubleValue: {
get(){
//this function will determine what is displayed in the input
return this.value*2;
},
set(newVal){
//this function will run whenever the input changes
this.value = newVal/2;
}
}
}
Then you can use <input v-model="doubleValue"></input>
if you just want the tag to display a method result, use <tag>{{method_name(data_attribute)}}</tag>
Agree with the :value and #change combination greenymaster.
Even when we split the computed property in get/set, which is help, it seems very complicated to make it work if you require a parameter when you call for get().
My example is a medium sized dynamic object list, that populates a complex list of inputs, so:
I can't put a watch easily on a child element, unless I watch the entire parent list with deep, but it would require more complex function to determine which of the innter props and/or lists changed and do what fromthere
I can't use directly a method with v-model, since, it works for providing a 'get(param)' method (so to speak), but it does not have a 'set()' one
And the splitting of a computed property, have the same problem but inverse, having a 'set()' but not a 'get(param)'