I'm getting this error from vue
[Vue warn]: Property or method "product" 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 sure where I went wrong to get that error. Here is my code
Home.vue
<template>
<div class="container">
<h1>This is the product page</h1>
</div>
</template>
<script>
export default {
props: ['product'],
data() {
return {
}
},
mounted() {
console.log(this.product);
}
}
</script>
and this is my product.blade.php
<div class="row">
<div class="col-md-12 mt-5">
<div id="app">
<home :product="product"></home>
</div>
</div>
</div>
and this is in my ProductsController
public function show(Product $product)
{
return view('welcome', [
'product' => $product
]);
}
<home :product="{{ $product }}"></home>
The product is coming from the your controller and to use it in blade, you have to use {{ }}
Related
I have two errors in my Vue components due to when I mount the component. The console log report shows me these 404 errors
1)[Error] Failed to load resource: the server responded with a status of 404 (Not Found) localhot8000/movies/getComments
2)[Error] Failed to load resource: the server responded with a status of 404 (Not Found) localhot8000/movies/comment/store
It cannot find my function, but I've look my code and I don't know how to fix this error.
Follow the code of my route on web.php:
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::resource('movies', App\Http\Controllers\MovieController::class);
Route::post('/comment/store','CommentController#store');
Route::get('/getComments/{movie}','CommentController#getComments');
Follow my code of my show.blade.php
#extends('layouts.app')
#section('content')
<div class="container my-2">
<div class="card mb-3">
<img src="{{ asset('images/movies/' . $movie->image) }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{$movie->title}}</h5>
<p class="card-text"> {{$movie->description}}</p>
<p class="card-text"><small class="text-muted">{{$movie->actor}}</small></p>
<p class="card-text"><small class="text-muted">{{$movie->gender}}</small></p>
<p class="card-text"><small class="text-muted"> {{$movie->duration}}</small></p>
</div>
</div>
</div>
<div class="card-body">
<comment-component :userid="{{Auth::user()->id}}" :movieid="{{$movie->id}}"></comment-component>
<get-comments-component :userid="{{Auth::user()->id}}" :movieid="{{$movie->id}}"></get-comments-component>
</div>
</div>
<span></span>
<button type="button" class="btn btn-warning">Back to Movies</button>
</tr>
</div>
</thead>
#endsection
Follow my code of my CommentComponent.vue
<template>
<div class="card text-center">
<div class="card-header">
Comments
</div>
<div class="card-body">
<h5 class="card-title">Nome user</h5>
<textarea name="comment" :v-model="formData.comment" class="form-control mb-1" rows="2" placeholder="Write a comment here..." ></textarea>
<button class="btn btn-success float-right" #click="commentStore">Add Comment</button>
</div>
<div class="card-footer text-muted">
2 days ago
</div>
</div>
</template>
<script>
export default {
props:['userid','movieid'],
data(){
return{
formData:{
comment:'',
user_id:this.userid,
movie_id:this.movieid
}
}
},
methods:{
commentStore(){
axios.post('comment/store',this.formData).then((response)=>{
console.log(response.data)
this.formData.comment=''
}).catch((error)=>{
console.log(error)
});
}
}
}
</script>
Follow my code of my GetCommentsComponent.vue
<template>
<div class="card text-center">
<div class="card-header">
Comments
</div>
<div class="card-body">
<h5 class="card-title">Nome user</h5>
<p v-for="(comment,index) in comments" :key="index">
<span class="badge badge-pill badge-light">{{ comment.user.name }} Commented: </span> {{ comment.comment }}
</p>
</div>
<div class="card-footer text-muted">
2 days ago
</div>
</div>
</template>
<script>
export default {
props:['userid','movieid'],
data(){
return{
comments:{}
}
},
mounted(){
this.getComments()
this.interval=setInterval(function(){
this.getComments()
}.bind(this),500)
},
methods:{
getComments(){
axios.get('getComments/'+this.movieid).then((response)=>{
this.comments = response.data
}).catch((errors)=>{
console.log(errors)
});
}
}
}
</script>
Follow my cod of my App.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue').default;
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('comment-component', require('./components/CommentComponent.vue').default);
Vue.component('get-comments-component', require('./components/GetCommentsComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
});
Follow my code of my Commentcontroller
<?php
namespace App\Http\Controllers;
use App\Models\Movie;
use App\Models\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller
{
public function store(Request $request)
{
//$request->all();
$comment = new Comment;
$comment->insert([
'movie_id' => $request->movie_id,
'user_id' => $request->user_id,
'comment' => $request->comment,
]);
return response()->json($comment);
}
public function getComments(Movie $movie)
{
return response()->json($movie->comments()->with('user')->latest()->get());
}
}
Code for my Eloquent models:
User
public function movies()
{
return $this->hasMany('App\Movie');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
Movie
public function user(){
return $this->belongsTo('App\User');
}
public function comments(){
return $this->hasMany('App\Comment');
}
}
Comment
public function user(){
return $this->belongsTo('App\User');
}
public function movie(){
return $this->belongsTo('App\Movie');
}
}
The issue isn't being caused by Vue failing to mount the components. The HTTP 404 errors are due to your axios() calls trying to load incorrect URLs. You're using relative URLs which will be affected by the current page URL.
If we look at your routes, we have these two entries:
Route::post('/comment/store','CommentController#store');
Route::get('/getComments/{movie}','CommentController#getComments');
Which create the following URLs:
localhot:8000/comment/store
localhot:8000/getComments/{movie}
You can use php artisan route:list to see a list of the URLs available in your Laravel app.
When we look at the two Vue components that reference these URLs, you'll see the following:
axios.get('getComments/'+this.movieid).then((response)=>{ ...
axios.post('comment/store',this.formData).then((response)=>{ ...
You're using a route::resource('movies') Resource Controller, so your show() method will have the URL of localhot:8000/movies/{id}.
This means you're Ajax calls are expecting URLs of:
localhot:8000/movies/comment/store
localhot:8000/movies/getComments/{movie}
which leads to the HTTP 404 errors.
The fix should be a quick one: your just need to update your Axios calls to ensure they're referring the correct URLs:
axios.get('/getComments/'+this.movieid).then((response)=>{ ...
^ added forward slash to get correct URL
axios.post('/comment/store',this.formData).then((response)=>{ ...
^ added
I'm using Vue.js with Laravel and facing a problem. I want to pass category id from the blade file to the Vue.js component as a prop. But don't know what is good practice and the right way for this.
I've defined the route something like this:
Route::view('/categories/{category}/edit', 'edit')->name('categories.edit');
and my edit.blade.php file is:
#extends('master')
#section('vue')
<div id="app">
<categories-edit :id=""></categories-edit>
</div>
#endsection
The Vue.js component code is:
<template>
<div class="container py-5">
<div class="row">
<div class="col-lg-12">
<div class="mb-3">
<label for="name" class="form-label">Name:</label>
<input type="text" v-model="formState.name" name="name" class="form-control" id="name" placeholder="Category Name" autocomplete="off">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CategoriesEdit',
props: ['id'],
data: function () {
return {
formState: {
name: '',
photo: ''
}
}
},
mounted() {
},
methods: {
loadInitialData: function () {
const self = this;
axios.get(``).then(function (response) {
}).catch(function (err) {
});
}
}
}
</script>
When I'm entering the URL in the web browser. I'm getting this error.
http://example.test/categories/1/edit
Output:
Undefined variable $category
Since you are using Route::view() you do not have the traditional way of getting route parameters and pass them to the view. Luckily you can always get these on the request object and there is a request() helper that makes it easier for Blade views.
<categories-edit :id="{{ request()->route('category') }}"></categories-edit>
My errors:
app.js:44406 [Vue warn]: Property or method "__" 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.
found in ---> <ChatComponent> at resources/js/components/ChatComponent.vue
app.js:44406 [Vue warn]: Error in render: "TypeError: vm._ is not a function" found in
---> <ChatComponent> at resources/js/components/ChatComponent.vue
TypeError: vm._ is not a function.
<template>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="card">
<div class="card-body minh overflow-auto"></div>
</div>
<div class="mt-3">
<div class="form-group">
<div class="input-group mb-3">
<input
type="text"
class="form-control"
v-bind:placeholder="placeholder"
aria-label="Recipient's username"
aria-describedby="button-addon2"
v-model="messageField"
/>
<div class="input-group-append">
<button class="btn btn-primary" type="button" id="button-addon2">{{__('auth.submit')}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
let messages = {};
export default {
data() {
return{
messages: {},
messageField: ""
}
},
props:[
'placeholder'
],
mounted() {
this.getMessagess();
},
methods: {
getMessagess() {
axios
.get("/messagefetch")
.then(response => {
this.messages = response.data;
})
.catch(function(error) {
console.log(error);
});
},
postMessage() {
axios
.post("/api/messagesend", {
api_token: this.user.api_token,
message: this.messageField
})
.then(response => {
this.message.push(response.data);
this.messageField = "";
})
.catch(function(error) {
console.log(error);
});
}
}
};
</script>
I get my messages from the database and my prop placeholder is also good but i dont see my component in the front-end. Also, I get 3 errors for functions made by vue.js itself, which get compiled and put in app.js. Im new at vue.js so im not sure what im doing wrong
You are mixing frontend and backend functions. The __ function is a laravel specific helper for localisation of text. But you cannot use a laravel php function inside Vue JavaScript. Therefore you get errors that the function is not found, etc.
You need to configure localisation separately for your frontend. Have a look at: https://kazupon.github.io/vue-i18n/
How to access axios result from vue component in blade file? I tried accessing {{value}} within 'app' div also. But the error still remains. I want to generate partial views based on the value of axios response.
IssueComponent.vue
<template>
<div>
<div class="form-group">
<label>Enter Accession No</label>
<input
type="text"
name="accession_no"
placeholder="Accession No"
class="form-control"
v-on:keyup.enter="getData()"
v-model="query"
/>
</div>
<div>
<button class="btn btn-info" #click.prevent="getData()">Check</button>
</div>
</template>
<script>
export default {
data() {
return {
query: "",
value: []
};
},
methods: {
getData: function() {
var self = this;
axios
.get("/issue-getdata", { params: { q: self.query } })
.then(function(response) {
self.value = response.data;
})
.catch(function(error) {
console.log(error);
})
.then(function() {
});
}
}
};
</script>
create.blade.php
<form action="/issue" method="POST">
<div id="app">
<issue-component></issue-component>
</div>
{{value}} ///////// Undefined constant error
<button type="submit" class="button-btn btn-success">Submit</button>
#csrf
</form>
Controller Method
public function getData(Request $request){
$input = $request->q;
$acsNo = preg_replace("/[^0-9]/", "", $input);
$acsNoIssued = Issue::where('accession_no', '=', $acsNo)->where('is_returned', null)->orwhere('is_returned', 0)->first();
return response()->json($acsNoIssued);
}
The Error
Facade\Ignition\Exceptions\ViewException
Use of undefined constant value - assumed 'value' (this will throw an Error in a future version of PHP) (View: D:\ProgrammingSSD\laragon\www\ulclibrary\resources\views\issues\create.blade.php)
You can't. Blade is rendered server side. By the time your vue component makes the request, that {{ $value }} is already parsed and is now a static part of your view.
What you could do is save the state (the information) in VUE, and read it using another VUE component that will display the info (instead of blade).
Guide for states in vue
https://vuex.vuejs.org/guide/state.html
<form action="/issue" method="POST">
<div id="app">
<issue-component></issue-component>
</div>
<display-component-value></display-component-value> // Vue component that reads the state you want
<button type="submit" class="button-btn btn-success">Submit</button>
#csrf
</form>
I am new to Laravel and a complete noob to Vue. I searched many other Laravel/Vue posts but none seemed to be similar enough to get me to a solution. When attempting to load this component on my view I receive the following error
app.js:32654 [Vue warn]: Property or method "features" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
Please let me know what I am missing.
chrome.google.com/webstore/detail/vuejs-devtools/ shows that Vue is loaded
I would like to load data from an ajax call to my vue component. that can be updated on the fly by event handler
App.js
window.Vue = require('vue');
Vue.component('Example', require('./components/Example.vue'));
const app = new Vue({
el : '#app',
});
$(document).ready(function() {
$.ajaxSetup({
headers : {
'X-CSRF-TOKEN' : $('meta[name="csrf-token"]').attr('content')
}
});
})
Example.vue
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
}
</script>
bladefile
<head>
<meta name="csrf-token" content="INMA4kLlG32gfhf4Z3BBGIFxitrVCWzzqgqPfooEj">
// and yes Vue is loaded
</head>
<body>
<div id="app">
<example></example>
</div>
...
<script>
Vue.component('example',{
template: 'Example',
})
//returns the JSON listed below
someOtherObject.addListener('click', function(e) {
$.ajax({
url:json,
method:'GET',
success:function(msg){
app.data = JSON.parse(msg);
}
})
})
</script>
JSON
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.155083,
33.569672
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"MEADOWLARK ",
"type":"Single Family Home",
"client_id":"26",
"client_name":"Pulte Homes",
"city_name":"French Valley"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.151390,
33.543981
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"Testing Project",
"type":"Single Family Home",
"client_id":"83",
"client_name":"Testing Account",
"city_name":"Temecula Valley"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.223720,
33.571522
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"Oak Ridge",
"type":"Single Family Home",
"client_id":"98",
"client_name":"Woodside 05S LP",
"city_name":"Beaumont"
}
}
]
}
The features array must be declared either as a prop or part of the component data.
As a prop:
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
props: ['features']
}
</script>
As component data:
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
data: function() {
return {features: []}
}
}
</script>
If you use a prop, you'll need to bind the prop in the template. If you use component data, you'll need to update the success callback function in the AJAX request to correctly update the data of the component rather than the app as a whole.
Also, beware of the reactivity caveats for loading new data, as outlined in the docs.
EDIT: Full example solution using component data
Here's a working example using a simplified version of your example component. Note that to do this I used the ref attribute so that the component could be addressed directly. Using refs is described in the docs as an "escape hatch" that should only be used when strictly necessary. A better pattern might be an external store, such as Vuex.
Vue.component( "example", {
template: '<div><h1>Example Component!</h1><ul v-if="features.length"><li v-for="feature in features">{{ feature.name }}</li></ul></div>',
data: function() {
return { features : [] }
}
});
var app = new Vue( { el: '#app' });
//A function to represent the AJAX callback
var doMockAjax = function() {
var mockData = [{name: 'One'},{name: 'Two'},{name: 'Three'}];
app.$refs.example.features = mockData;
}
document.getElementById('load-data').addEventListener('click', function(e) {
//This simulates the ajax callback by populating the array asynchronously
setTimeout(doMockAjax,1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<example ref="example"></example>
</div>
<button id="load-data">Load</button>