Missing required prop: "id" at <AddProduct> - Laravel / Vue - laravel

i want to pass a value from laravel blade to a Vue Component:
my Laravel blade:
<div id="add_product">
<add-product :id="{{$product_id}}"></add-product>
</div>
my vue component:
export default {
props:{
id:{
required : true
}
},
mounted() {
console.log(this.id)
},
}
the problem is that i get this error :
Missing required prop: "id" at AddProduct
it took me 4hours trying to find out the problem, hope you can help.
The Repo:
https://github.com/SimodevStuff/shopify-add-product-clone
Edited:

try
<div id="add_product">
<add-product id="{{$product_id}}"></add-product>
</div>
id without :.
in Vue prop prefixed with : is a shorthand for v-bind. Meaning, you are binding a property to the component. But you need to pass a value.

Related

How to pass a value from Laravel blade to a vue component?

I am working on laravel / vue project and i want to pass a value from laravel blade to the vue component but i get this error :
Missing required prop: "id" at
The vue component:
export default {
props:{
id:{
required : true
}
},
mounted() {
console.log(this.id)
},
}
The Laravel blade:
<div id="add_product">
<add-product :id="{{$product_id}}"></add-product>
</div>
https://router.vuejs.org/guide/essentials/passing-props.html
you should add props true to router
{ path: '/user/:id', component: User, props: true },
Edit :
Just remove : from :id
<add-product id="{{$product_id}}"></add-product>

vue3 Cannot read property 'insertBefore' of null

I'm getting this error when i try to update my data fields in vuejs.
data() {
return {
form : useForm({
imageFile : null,
img_id : null,
}),
product_images : this.images,
}
},
here I'm updating the product_images after the success of post request sent by the user.
like this.
this.form.post(url, {
onStart : () => {
Inertia.on('progress', (event) => {
if (event.detail.progress.percentage) {
NProgress.set((event.detail.progress.percentage / 100) * 0.98);
}
});
},
onFinish : () => {
this.product_images = this.images;
},
})
showing the product_images in template be like
<div v-for="image in product_images" class="col-xl-4 col-lg-6 col-12 mb-3" :key="image.id">
<input-image #changeImage="onChangeImage" :id="image.id" :image="image.image" />
</div>
when product_images changes after the post request, product_images not update in DOM but get this error why?
app.js:12889 Uncaught (in promise) TypeError: Cannot read property 'insertBefore' of null
at insert (app.js:12889)
at mountElement (app.js:9604)
at processElement (app.js:9545)
at patch (app.js:9465)
at patchKeyedChildren (app.js:10315)
at patchChildren (app.js:10093)
at processFragment (app.js:9839)
at patch (app.js:9461)
at patchKeyedChildren (app.js:10174)
at patchChildren (app.js:10117)
Unfortunately the vue error message is not very helpful.
In my case, I had some uninitialized data in the html template like this:
<template>
<div>
{{ data.xyz }}
</div>
</template>
Change this to either:
<template v-if="!!data">
<div>
{{ data.xyz }}
</div>
</template>
Or:
<template>
<div>
{{ data?.xyz }}
</div>
</template>
I fixed it by updating my Vue to the latest version (vue#3.2.20).
In my case, was mistakenly calling app.mount('#app') twice.

How to avoid warning "mutating a prop directly" using Vue and Laravel

I am using Laravel 7 and Vue.js 2.
I want to pass an eloquent query result from a controller to a Vue.js component (passing through a View and another component).
This is my controller:
$permissions = Permission::select('id')->get();
return view('admin')->with(['permissions'=>$permissions]);
This is my view:
<div id="app">
<admin-panel :permissions="{{ $permissions }}"></admin-panel>
</div>
This is admin-panel component (passing data through props):
<template>
<div>
<admin-operations></admin-operations>
<hr>
<insert-employee :permissions="permissions"></insert-employee></div>
</template>
This is insert-employee component script:
<script>
export default {
components: {
},
props: ['permissions'],
mounted() {
console.log('Component mounted.');
},
computed:{
},
data: function() {
return {
}
},
methods: {
}
}
</script>
This is the select in insert-employee component:
<select required v-model="permissions" class="form-control" id="permissions">
<option v-for="permission in permissions" :value="permission.id" :key="permission.id">
{{ permission.id }}
</option>
</select>
The results of the query should be visualized in the select options.
However in the select I can visualize correctly the values in the options, but when I select an option the selection doesn't work and in the console appears two times the following warning:
app.js:40160 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "permissions"
found in
---> <InsertEmployee> at resources/js/components/InsertEmployee.vue
<AdminPanel> at resources/js/components/AdminPanel.vue
<Root>
Can help?
Let's try this. I think we're just mixing the values up a bit. I'll try to think of props that are passed in as a read only thing. In this case permissions is an array that holds the id's of each permission.
Next we'll want to use that array to give our user object some values. This way we aren't trying to manipulate values of permissions. That's where Vue was initially getting angry.
<script>
export default {
components: {},
props: {
permissions: {
type: Array,
required: true,
default: () => [],
}
},
mounted() {
console.log('Component mounted.');
},
computed:{},
data: () => ({
user: {
permissionId: "",
}
}),
methods: {},
}
</script>
Then in your component template:
<select required v-model="user.permissionId" class="form-control" id="user-permissionId">
<option v-for="permission in permissions" :value="permission.id" :key="permission.id">
{{ permission.id }}
</option>
</select>

Two way bind into template

I've been searching for hours now and i just can't figure it out..
Is there any way that i could bind the data from an input, send it to the template and here use the data?
Let me paint the picture...
edit.php
<form>
<input v-model="?">
</form>
<prod-preview name="somehowsendthename"></prod-preview>
prod-preview.vue
<template>
<h1>{{ name }}</h1>
</template>
<script>
export default {
name: "product-preview",
props: ["name"],
data(){
return {
name: ""
}
},
}
Don't worry about binding the actual component, that works. Thank you
Something like this should work:
// edit.vue
<template>
<form>
<input v-model="name">
</form>
<prod-preview :name="name"></prod-preview>
</template>
<script>
import ProdPreview from './prod-preview'
export default {
name: "edit",
components: [ProdPreview],
data(){
return {
name: ""
}
},
}
</script>
// prod-preview.vue
<template>
<h1>{{ name }}</h1>
</template>
<script>
export default {
name: "product-preview",
props: ["name"]
}
</script>
To pass a name in from the blade and bind it to the data in the view component, you want a prop with a different name, something like initialName and then set the data name that you bind with v-model using the initialName like this...
export default {
name: "product-preview",
props: ["initialName"],
data(){
return {
name: this.initialName
}
},
}
Note that html attributes are case insensitive so you'd pass that in like this and it will be received by the correct prop:
<prod-preview initial-name="{{ $name }}"></prod-preview>
You can now v-bind to "name" and it will keep the data attribute name current as you change that input and you won't be attempting to change a prop which should not be done.

Laravel vue-multiselect error

I am trying to implement vue-multiselect (version 1.1.3) with Laravel 5.
In my vue file I have this code:
<template>
<div class="dropdown">
<multiselect
:seleted="multiValue"
:show-labels="false"
:options="options"
:placeholder="placeholder"
:searchable="true"
:allow-empty="false"
:multiple="true"
key="name"
label="name"
#update="updateSelected"
></multiselect>
<label v-show="showLabel" for="multiselect"><span></span>Language</label>
</div>
</template>
<script>
import { Multiselect } from 'vue-multiselect';
export default {
components: { Multiselect },
props: {
selected: null,
options: {
type: Array, default: function () {
return []
}
},
placeholder: 'Select...'
},
methods: {
updateSelected (newSelected) {
this.selected = newSelected
}
}
}
</script>
In my blade file:
<div class="form-group">
<drop-down
:options="{{ $members_list->toJson() }}"
></drop-down>
</div>
In my controller:
$members = DB::table('members')
->orderBy('member_first_name', 'asc')
->get();
$members_list = $members->map(
function($member) {
return [
"value" => $member->member_id,
"label" => $member->member_first_name. " ". $member->member_last_name
];
}
);
When I run the page I get a select list with all the members in it, but when I try to select one, it turns Red, it is added to the selected list on top but I cannot select more options and in firebug I get this error:
[Vue warn]: You are setting a non-existent path "selected" on a vm instance. Consider pre-initializing the property with the "data" option for more reliable reactivity and better performance.
What am I missing?
Typo might be causing issues?
:seleted="multiValue"
Should be :selected="multiValue"
BTW :selected is deprecated in the version 2.0. :value has taken it's place.
I think it is because there is no variable called 'multiValue' in your component.
In :seleted="multiValue" , using the variable "options" instead of "multiValue"

Resources