Laravel 8 - Eloquent Relationship cannot access relation properties / values - laravel-8

Model 1: Walks
return $this->belongsTo('App\Models\Device','device_uuid','device_uuid');
}
Model 2: Device
public function walks() {
return $this->hasMany('App\Models\Walks','device_uuid','device_uuid');
}
In my index file:
<table class="table table-bordered">
<tr>
<th>No</th>
<th>Walk Date</th>
<th>Device Name</th>
<th>In</th>
<th>Out</th>
<th width="280px">Action</th>
</tr>
#foreach ($walks as $walk)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $walk->walk_datetime }}</td>
<td>{{ $walk->device->device_uuid }}</td> <========
<td>{{ $walk->walk_in }}</td>
<td>{{ $walk->walk_out }}</td>
<td>
<form action="{{ route('walks.destroy',$walk->id) }}" method="POST">
<a class="btn btn-primary" href="{{ route('walks.edit',$walk->id) }}">Edit</a>
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
#endforeach
</table>
this causes errors:
<td>{{ $walk->device->device_uuid }}</td> <========
"Trying to get property 'device_uuid' of non-object"
If I do this:
<td>{{ $walk->device }}</td>
I get:
{"id":1,"device_uuid":"1902101300368","device_name":"Test 1","created_at":null,"updated_at":null}
which means the relation works correct.
Is there any other way that I should use to access the "device_mame" attribute?
Related to questions below.. All walks has a valid device linked.
walks list. This is what shows if I print -> $walk->device
walk list (DB)
devices list (DB)

:) It seems to me that some Walks don't have a Device. That's why it (usually) throws that error.
Similar problem on Laracasts.
Or what you can do is use ternary operators
<td>{{(isset($walk->device->device_uuid)? $walk->device->device_uuid : ''}}</td>

Related

Using v-for in a table

I have a table is populated with some info and I would like to format the table like the picture
Unfortunately the excel sheet which I have no control over is formatted so:
I want any row that has only a Equipment type to span whole row. All other rows should appear as normal table row.
I am using following vue template:
<table>
<caption>
SHS Scrap Table
</caption>
<thead>
<tr>
<th>Make</th>
<th>Model #</th>
<th>Bar Code</th>
<th>Serial #</th>
<th>Location</th>
<th>Condition</th>
</tr>
</thead>
<tbody v-for="item in scrapDataEmptyRowsRemoved" :key="item">
<tr v-if="item['Equipment Type']">
<td class="equipt-type" colspan="6">
Equipment Type - {{ item["Equipment Type"] }}
</td>
</tr>
<tr v-else>
<td>{{ item["Make"] }}</td>
<td>{{ item["Model #"] }}</td>
<td>{{ item["Bar Code"] }}</td>
<td>{{ item["Serial #"] }}</td>
<td>{{ item["Location"] }}</td>
<td>{{ item["Condition"] }}</td>
</tr>
</tbody>
</table>
The only problem is that looking in Devtools I see that every row has a Tbody which is not semantically correct. Any idea's on how to correct this. If I use a container around the v-if v-else all formatting breaks down.Thanks...
Update the only problem is Vite is objecting to moving :key attribute to the v-else:
I dont what other unique key they want.
Update II - Ok apparently if I use different object keys Vite is ok with that ie :key="item['Equipment Type'] and on v-else :key="item['Make']. Does that seem correct?
You can move the v-for in a template tag, that won't be rendered in the DOM.
<tbody>
<template v-for="item in scrapDataEmptyRowsRemoved" :key="item">
<tr v-if="item['Equipment Type']">
<td class="equipt-type" colspan="6">
Equipment Type - {{ item["Equipment Type"] }}
</td>
</tr>
<tr v-else>
<td>{{ item["Make"] }}</td>
<td>{{ item["Model #"] }}</td>
<td>{{ item["Bar Code"] }}</td>
<td>{{ item["Serial #"] }}</td>
<td>{{ item["Location"] }}</td>
<td>{{ item["Condition"] }}</td>
</tr>
</template>
</tbody>

How to connect/link input with Ng Zorro Table (Create search table)

I wish to create a search feature in my NG ZORRO table by linking/connect nz-input with nz-table. Is is possible to do so? Or is there any other methods to do so?
<uic-page>
<p>user-details works!</p>
<nz-input-group [nzSuffix]="suffixIconSearch">
<input type="text" nz-input placeholder="input search text" />
</nz-input-group>
<ng-template #suffixIconSearch>
<i nz-icon nzType="search"></i>
</ng-template>
<nz-table #basicTable [nzData]="listOfData">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Address</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of basicTable.data">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
<td>
<a>Action δΈ€ {{ data.name }}</a>
<nz-divider nzType="vertical"></nz-divider>
<a>Delete</a>
</td>
</tr>
</tbody>
</nz-table>
Thanks.
This should work fine
Just make an event on the input and change the data based on that
also make sure you make copy of the data (if the search is client-side) to avoid lose the data

Show JSON Data property in for each loop of Vue.js Template

JSON Data
{
"Data":[
{
"Country":"{\"CountryID\":1,\"Name\":\"United States\",\"Code\":\"US\"}",
"Currency":"{\"CountryID\":1,\"Code\":\"USD\",\"Symbol\":\"$\"}"
},
{
"Country":"{\"CountryID\":1,\"Name\":\"United States\",\"Code\":\"US\"}",
"Currency":"{\"CountryID\":1,\"Code\":\"USD\",\"Symbol\":\"$\"}"
}
]
}
Vue.js Code
<table class="table table-bordered mb-0" v-if="MembershipRecords.length > 0">
<thead>
<tr>
<th>Currency</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr v-for="Record in Records">
<td>{{ Record.Currency }}</td>
<td>{{ Record.Country }}</td>
</tr>
</tbody>
</table>
Below is how it looks on web page.
When I tried like this Record.Country.Name it displays nothing.
Can you please suggest?
It looks like you have stringified data in the records column. Try this:
<tr v-for="Record in records">
<td>{{ JSON.parse(Record.Currency).Code }}</td>
<td>{{ JSON.parse(Record.Country).Name }}</td>
</tr>
https://jsfiddle.net/01ogLreg/

How to add class name using Vue.js to a table column which is part of a Vue.js Template? [duplicate]

This question already has answers here:
Difference between v-bind and {{}}?
(3 answers)
How can I solve "Interpolation inside attributes has been removed. Use v-bind or the colon shorthand"? Vue.js 2
(6 answers)
Closed 5 years ago.
I need to assign class name from my visitor object (visitor.iso_code) to a table column. However Vue.js will not allow me to do it this way. I've tried v-bind:class and :class and neither of them work. Any help would be appreciated. Thank you in advance.
<template lang="html">
<div>
<table id="vue_generated_visitors_table" class="table">
</table>
<tbody>
<tr v-for="visitor in visitors_table">
<th scope="row">{{ visitor.id }}</th>
<td>{{ visitor.created_at }}</td>
<td><img src="images/blank.png" class="{{visitor.iso_code}}" /> {{ visitor.country }}</td>
<td>{{ visitor.city }}</td>
<td>{{ visitor.state_name }}</td>
<td>{{ visitor.postal_code }}</td>
<td>{{ visitor.lat }}</td>
<td>{{ visitor.lon }}</td>
<td>{{ visitor.timezone }}</td>
<td>{{ visitor.currency }}</td>
<td>{{ visitor.userAgent }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script type="text/javascript">
export default {
props: ['visitors_table','method'],
data () {
return {
}
},
methods: {}
}

Displaying data using v-for with VueJS

Looping data from an array. The problem is that the loop creates 3 empty tables, guessing it's because im calling item. 3 times. If I want the data from the array without Vue creating empty tables, how should I display the data? Been trying to use {{users.firstname}} without the v-for loop but doesn't seem to work.
<table v-for="item in users">
<tbody>
<tr>
<td>{{ item.username }}</td>
</tr>
<tr>
<td>{{ item.firstname }}</td>
</tr>
<tr>
<td>{{ item.lastname }}</td>
</tr>
</tbody>
</table>
Solved using <template v-for="item in users" v-if="item.username && item.firstname && item.lastname">. No extra elements are printed out.
If you want to create 3 rows per user, use a <template> tag to group them, and use v-for on that template:
<table>
<tbody>
<template v-for="item in users">
<tr>
<td>{{ item.username }}</td>
</tr>
<tr>
<td>{{ item.firstname }}</td>
</tr>
<tr>
<td>{{ item.lastname }}</td>
</tr>
</template>
</tbody>
</table>
Have a look at this fiddle for an example: https://jsfiddle.net/nfa43bhq/