Laravel vuejs 'Cannot read property of data' error - laravel

Been trying to figure this out for half an hour now and I cant seem to fix the error, here is my vue component:
<template>
<div class="container">
<div class="row mt-5">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Country Lists</h3>
</div>
<!-- /.card-header -->
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tr>
<th>Year</th>
</tr>
<tr v-for="country in countries.data" :key="country.id">
<td>{{country.name}}</td>
</tr>
</table>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
</div>
</div>
</div>
</template>
<script type="text/javascript" src="node_modules/vuejs/dist/vue.min.js"></script>
<script type="text/javascript" src="node_modules/vue-simple-search-dropdown/dist/vue-simple-search-dropdown.min.js"></script>
<script>
export default {
data(){
return{
country : {},
form: new Form({
id : '',
})
}
},
methods: {
loadCountry(){
axios.get('api/country').then(({data}) => (this.countries = data));
}
},
mounted() {
this.loadCountry();
Fire.$on('reloadAfter',() => {
this.loadCountry();
});
}
}
</script>
When I load the page the table wont display, but when I check the network from the developer tab in chrome, it can and loads the data, however it displays this error in the console 'Cannot read property 'data' of undefined'.
Thanks in advance.

The problem is here
<tr v-for="country in countries.data" :key="country.id">
<td>{{country.name}}</td>
</tr>
countries is not defined yet.
You can, for example, add it to data()
data(){
return{
countries : {},
},
}
And test the presence of data
<table v-if="countries.data" class="table table-hover">

Related

Vue component doesn't load

I want to load a vue component after I click on the "next" button. The project is laravel + vue.
The components load if I put them direct into laravel blade(you can see them below) but if I try to open component from the component it does'nt work. I don't get eny error it just stays the same component. The route in the address bar changes to the route that it should change... I mean it's really starnge.
app.js:
require('./bootstrap');
window.Vue = require('vue').default;
import Vue from 'vue';
import VueRouter from 'vue-router';
import { routes } from './routes';
Vue.use(VueRouter);
Vue.component('productinfo-index', require('./components/productInfo/index.vue').default);
Vue.component('audit-index', require('./components/audit/index.vue').default);
Vue.component('audit-info', require('./components/audit/auditInfo.vue').default);
const router = new VueRouter({
mode: 'history',
routes: routes
});
const app = new Vue({
el: '#app',
router: router
});
Routes.js:
import ProductInfoIndex from './components/productInfo/index';
import Audit from './components/audit/index';
import AuditInfo from './components/audit/auditInfo';
export const routes = [
{
path: '/productInfo',
name: 'ProductInfoIndex',
component: ProductInfoIndex
},
{
path: '/audit',
name: 'Audit',
component: Audit
},
{
path: '/audit/info',
name: 'AuditInfo',
component: AuditInfo
}
];
Index.vue:
<template>
<div>
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Inventorizacija</h1>
</div>
<div class="row">
<div class="card mx-auto">
<div class="card-header">
<router-link
:to="{name: 'AuditInfo'}"
class="btn btn-primary mb-2"
>Next</router-link>
</div>
<!-- <div v-if="showMessage">
<div class="alert alert-success">{{ message }}</div>
</div> -->
<div class="card-body">
<table class="table">
<thead>
<tr>
<th scope="col">Pavadinimas</th>
<th scope="col">Pradėta</th>
</tr>
</thead>
</div>
</div>
</div>
</div>
</template>
AuditInfo.vue(the component that should be loaded):
<template>
<div class="row">
<div class="card mx-auto">
<div class="card-header">
<router-link
:to="{name: 'Audit'}"
class="btn btn-primary mb-2"
>Back</router-link>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th scope="col">Pavadinimas</th>
<th scope="col">Pradėta</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
You should put <router-view /> somewhere in the index.vue for rendering router component.

Fill table depending dropdown list selected value in Laravel vuejs Axios

I am trying to get data in the table code are as below
I want to autofill the table with the depending dropdownlist selected value. i’ve been finding solution since days but didn’t get any success. I’m very new at this.
If anyone could help to get me out from this issue i’ll be very grateful. Thank You.
Here Is my HTML code
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">employees Table</h3>
<div class="card-body">
<div class="md-3">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<select
name="company_id"
id="company_id"
:class="{'is-invalid':form.errors.has('company_id')}"
class="form-control"
v-model="form.company_id"
#change="getEmployeesbyCompany()"
>
<option value selected>Select Company</option>
<option
v-for="Company in Companies.data"
:key="Company.id"
>{{Company.Company}}</option>
</select>
<has-error :form="form" field="company_id"></has-error>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /.card-header -->
<div class="card-body table-responsive p-0">
<div class="col-md-12"></div>
<table class="table table-hover">
<!-- <thead>
</thead>-->
<tbody>
<tr>
<th>ID</th>
<th>Badge#</th>
<th>Company</th>
<th>BadgeType</th>
<th>Nationality</th>
<th>Last Name</th>
<th>First Name</th>
<th>Telphonenumber</th>
<th>Position</th>
<th>SupervisorName</th>
<th>SupervisorNumber</th>
<th>Issuedate</th>
<th>Tazker</th>
<th>Expiredate</th>
<th>Serialnumber</th>
<th>Modify</th>
</tr>
<tr v-for="employee in employees.data" :key="employee.id">
<td>{{employee.id}}</td>
<td>{{employee.BadgeCode|UppCaseFirstLetter}}</td>
<!-- <td>{{employee.company_id}}</td> -->
<td>{{Company.Company}}</td>
<td>
<span class="tag tag-success">{{employee.BadgeType}}</span>
</td>
<td>{{Nationality.nationality}}</td>
<td>{{employee.lastname |UppCaseFirstLetter}}</td>
<td>{{employee.firstname |UppCaseFirstLetter}}</td>
<td>{{employee.telphonenumber |UppCaseFirstLetter}}</td>
<td>{{employee.position |UppCaseFirstLetter}}</td>
<td>{{employee.supervisorname |UppCaseFirstLetter}}</td>
<td>{{employee.supervisornumber|UppCaseFirstLetter}}</td>
<td>{{employee.Issuedate|mydate}}</td>
<td>{{employee.tazker|UppCaseFirstLetter}}</td>
<td>{{employee.Expiredate |mydate}}</td>
<td>{{employee.serialnumber |UppCaseFirstLetter}}</td>
</tr>
</tbody>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer">
<pagination :data="employees" #pagination-change-page="getResults"></pagination>
</div>
</div>
<!-- /.card -->
</div>
My #change="getEmployeesbyCompany" method:
methods: {
getEmployeesbyCompany: function() {
axios.get("api/getEmployees", {
params: {company_id: this.form.company_id}})
.then( function(response) {this.employees = response.data;}.bind(this)
);
}
Route:
Route::get('getEmployees','API\EmployeeController#getEmployees');
My getEmployees(){} method:
public function getEmployees(Request $request)
{
$employees = Employee::where('company_id',$request->company_id)->get();
return $employees;
}
My data() in Vue Component:
data() {
return {
editMode: false,
selectedTicketInvoiceId: false,
Companies: {},
Nationalities: {},
employees: {},
form: new Form({id: "",BadgeCode: "",BadgeType: "",company_id: "",
nationality_id: "",lastname: "",firstname: "",telphonenumber: "",
position: "",supervisorname: "", supervisornumber: "",
issuedate: "",tazker: "", expiredate: "", serialnumber: "" })};
}
The issue is that your table is using employees.data in the v-for directive. This works fine on the initial page load, because employees is a Laravel paginator, so the data property is defined, and it contains the array of employees, as expected.
However, your controller function is simply returning an array of employees. You are saving that array to your Vue instance's employees property. So now employees.data is undefined, and your table is empty.
To fix the issue, you can update your controller function like this:
public function getEmployees(Request $request)
{
$employees = Employee::where('company_id',$request->company_id)->get();
return ['data' => $employees]; // or return response()->json(['data' => employees]);
}

Why output using ajax not display in table but json format?

I want to create a searching filters and display the output using ajax.
This is the button for submit the data:
{!! Form::open(['method' => 'POST', 'action' => 'Modul\CarianAnugerahController#search']) !!}
//Form for filter here...
{{ Form::submit('Cari', ['class' => 'btn btn-primary', 'id' =>'search']) }}
{!! Form::close() !!}
This is the output table under the form:
<div class="panel panel-default">
<div class="panel-heading">Senarai Calon Anugerah</div>
<div class="panel-body">
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif
#if(Auth::check())
<div class="container table-responsive col-lg-12">
<!-- <div class="container text-center"> -->
<table class="table table-striped table-bordered" id="calon_table" >
<thead>
<tr>
<td class="text-center col-lg-3"><strong>Name</strong></td>
<td class="text-center"><strong>Action</strong></td>
<!-- <td class="text-center"><strong>Lihat Rekod</strong></td> -->
</tr>
</thead>
<tbody id="calon_anugerah">
</tbody>
</table>
<!-- </div> -->
</div>
#endif
#if(Auth::guest())
Anda perlu log masuk.
#endif
</div>
</div>
</div>
The ajax code to get the data is:
<script type="text/javascript">
$('#search').on('click', function(){
$.get("{{ URL::to('search-calon') }}",function(data){
$.each(data, function(i, value){
// alert(value.name);
var tr =$("<tr/>");
tr.append($("<td/>",{
text : value.name
}))
$('#calon_anugerah').append(tr);
});
})
})
</script>
I had queried the data using the code in CarianAnugerahController#search:
$query = DB::table('itemregistrations')
->select('itemregistrations.ItemRegistrationID','itemregistrations.name', 'itemregistrations.Nobadan');
if(request('umur')) {
$query->whereRaw('YEAR(CURDATE()) - lahir_yy >= ?', [request('umur')]);
}
if(request('negeri_lahir')) {
$query->where('NegeriID', request('negeri_lahir'));
}
if(request('kategori')) {
$query->where('CategoryID', request('kategori'));
}
if(request('pangkat')) {
$query->where('OperasiID', request('pangkat'));
}
$newitem = $query->get();
return response($newitem);
This is the route:
Route::resource('carian_anugerah', 'Modul\CarianAnugerahController');
Route::post('/search-calon', 'Modul\CarianAnugerahController#search');
I can get the value but it doesn't display in table..it shows the output in json format in a white page..
example output..in browser.
What is missing in the ajax code?

Info not displaying in modal, however no errors and Vue component works in console

Looking to display data in a modal. My set up is as follows:
app.js
Vue.component('modal', require('./components/Modal.vue'));
const app = new Vue({
el: '#vue',
data() {
return {
id: '',
booking_start: '',
booking_end: '',
car: [],
user: []
};
},
});
Modal.vue component:
<template>
<div id="modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<slot name="header"></slot>
</div>
<div class="modal-body">
<slot></slot>
</div>
<div class="modal-footer">
<slot name="footer"></slot>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<script>
export default {
name: 'modal',
mounted() {
console.log('Modal mounted.')
},
data() {
return {}
},
props: ['id', 'booking_start', 'car', 'user'],
mounted() {
}
}
</script>
Laravel blade:
<div id="vue">
<modal v-bind="{{json_encode($reservation)}}">
<template slot="header">
<strong>Vehicle Checkout</strong>
</template>
<p>Ready to check out this vehicle?</p>
<table class="table table-sm">
<tr>
<th>Vehicle Name</th>
<td><span id="reservation-car-name">#{{ car.name }}</span></td>
</tr>
<tr>
<th>Vehicle Make / Model</th>
<td><span id="reservation-car-make-model"></span></td>
</tr>
<tr>
<th>Vehicle Registration</th>
<td><span id="reservation-car-registration"></span></td>
</tr>
<tr>
<th>Odometer Start</th>
<td><span id="reservation-car-odometer"></span></td>
</tr>
</table>
<template slot="footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Checkout</button>
</template>
</modal>
</div>
At this point, I am just attempting to get the data to show in the modal.
Looking at the Vue Dev tools:
There are no errors in the console, and I can output the data I am after in the console.
I'm probably missing something very basic as I am new to Vue, but I can't for the life of me work out what it is.
Component tag replaced by template content, so put all content into modal component from component tag <modal>.your content.</modal>
Vue.component('modal',{
props:['car'],
template: `<div><template slot="header">
<strong>Vehicle Checkout</strong>
</template>
<p>Ready to check out this vehicle?</p>
<table class="table table-sm">
<tr>
<th>Vehicle Name</th>
<td><span id="reservation-car-name">{{ car.name }}</span></td>
</tr>
<tr>
<th>Vehicle Make / Model</th>
<td><span id="reservation-car-make-model">{{ car.model }}</span></td>
</tr>
<tr>
<th>Vehicle Registration</th>
<td><span id="reservation-car-registration">{{ car.reg }}</span></td>
</tr>
<tr>
<th>Odometer Start</th>
<td><span id="reservation-car-odometer">{{ car.odo }}</span></td>
</tr>
</table>
<template slot="footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Checkout</button>
</template>
</div>`
})
const app = new Vue({
el: '#vue',
data() {
return {
id: '',
booking_start: '',
booking_end: '',
car: {name:'test1',model:'gh201',reg:'201821542',odo:'2018-01-01'},
user: []
};
},
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="vue">
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<modal :car="car"></modal>
</div>
</div>
</div>
</div>
My other answers related this issue : router view and transition-group

VueJS inside Laravel, can't pass data using props

This is the code (very simple)
<div class="container" id="vueApp">
<div class="content">
<div class="title animated flipInX">BIG TITLE</div>
<p><strong>Some subtitle</strong></p>
<custom-button fa-icon="fa-home"></custom-button>
<custom-button fa-icon="fa-envelope"></custom-button>
<custom-button fa-icon="fa-info"></custom-button>
</div>
</div>
<template id="btn-template">
<span class="btn fa #{{ fa-icon ? fa-icon : 'fa-star-o' }} font-size-40"></span>
</template>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script>
Vue.component('custom-button', {
template: '#btn-template',
props: ['fa-icon'],
});
</script>
This is returnig fa-star-o and not the desired fa-icon. I really don't see any errors but I'm new to this so I'm hoping its something trivial.
I'm following this tutorial.
----SOLUTION----
<div class="container" id="vueApp">
<div class="content">
<div class="title animated flipInX">BIG TITLE</div>
<p><strong>Some subtitle</strong></p>
<custom-button fa-icon="fa-home"></custom-button>
<custom-button fa-icon="fa-envelope"></custom-button>
<custom-button fa-icon="fa-info"></custom-button>
</div>
</div>
<template id="btn-template">
<span class="btn fa #{{ faIcon }} font-size-40"></span>
</template>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script>
Vue.component('custom-button', {
template: '#btn-template',
props: {
faIcon: {
type: String,
default: 'fa-star-o'
}
}
});
</script>
The prop name should be faIcon (camelCased).
http://vuejs.org/guide/components.html#camelCase_vs-_kebab-case
https://jsfiddle.net/asccyLus/
Also, it is better to use a default value for the faIcon instead of the inline if like this:
props: {
faIcon: {
type: String,
default: 'fa-star-o'
}
},
https://jsfiddle.net/asccyLus/1/

Resources