Return Data from Database with vue Hi, I have two tables that has one to one relationship, when I try to access data from 2nd table, I get the "TypeError: Cannot read property 'bio' of null" .
Here my controller
return User::with('profile')->latest()->get();
RelationShip
public function profile(){
return $this->hasOne('App\StudentInfo');
}
Axios
axios.get("api/user").then(({ data }) => (this.users = data));
Table
{{ user.name }}
{{ user.email }}
{{ user.phone }}
{{ user.photo }}
{{ user.profile.bio}} //This gives me error when I remove It's working fine
<td>
<a href="">
<i class="material-icons">mode_edit</i>
</a>
<a href="">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
Cannot read property 'bio' of null"
Clearly user.profile is null.
Your relationship assumes that there is a user_id foreign key on the table associated with the StudentInfo model, is this correct?
Yes There is a user_id foreign key.. If I access like this {{user.profile}} the profile object is showing with all it's properties however if I change it to {{user.profile.bio}} I get an error.
created_at: "2018-10-03 06:33:47"
email: "[email protected] "
email_verified_at: null
id: 11
name: "test 2"
phone: "0739764608"
photo: "user.png"
profile: {id: 1, user_id: 11, phone: null, dob: "21 July 1989", id_number: "928525554555", gender: "male",…}
type: "admin"
updated_at: "2018-10-03 06:33:47"
Can you wrap that output in triple backticks --- ``` on its own line before the content and closed on its own line after?
Looks like:
address: "2nd Street↵Hillside" bio: "Some info here" user_id: 13
this is not returned as json(in correct form), that's why you cant access it @simangae
Its Actually array like this
[{id: 13, name:"Joseph WhatNot"......}
profile{ address: address: "2nd Street", bio:"Some info here" user_id: 13}
]
@simangae you try to access it as it is was json, that's why it's not working. :)
You can change
return User::with('profile')->latest()->get();
To
return User::with('profile')->latest()->first();
This will give you the newest user only.
If you need to show multiple users in you frontend you are going to have to loop through the JSON array that is returned to get each user in you html/blade/vue
the response object has property data:
axios.get('api/user')
.then(response => {
console.log(response.data);
this.users = response.data
})
.catch(error => console.log(error.response))
in controller:
$users = User::All();
return response()->json($users, 200);
@petritr I'm still leaning vuejs I'm not sure How can I access it
Using @marty12321 axios code to put the users in your data object you can do this in your template
<ul>
<li v-for="user in users" :key="user.id">
{{ user.profile.bio }}
</li>
</ul>
This will output each users bio in a list. Change the template to meet your needs
@marty12321 I'm still getting the same error..
User::all() does not return the profile
$users = User::with('profile')->latest()->get();
my controller
return response()->json($users, 200);
axios.get("api/user").then(response =>{this.users = response.data
}).catch(error => console.log(error.response));
Table
<tr v-for="user in users" :key="user.id">
<td></td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.phone }}</td>
<td>{{ user.photo }}</td>
<td>{{ user.profile.bio}}</td>
<td>
<a href="">
<i class="material-icons">mode_edit</i>
</a>
<a href="">
<i class="material-icons">delete</i>
</a>
</td>
</tr>```
@simangae in the controller:
return response()->json( User::all()->with('profile')->get() );
Then you can access it as you want to: {{ user.profile.bio}}, you can hear the rest as you had it before.
Can you share a formatted content of the output of
.then(response => {
console.log(response.data);
}
@simangae just do what i wrote and it will work :)
@petritr - Your suggestion won't change the response as axios will make a JSON request so larvael will return JSON by default and also misses the latest ordering of the question
return response()->json( User::all()->with('profile')->latest()->get() );
is equivalent to
return User::with('profile')->latest()->get();
We really need to see the data axios is returning to identify the issue
@D9705996 i just find more visual and easy to read when i do it as i did.
return response()->json( User::with('profile')->get() );
@D9705996
The output in the console
created_at: "2018-10-03 06:44:50"
email: "[email protected] "
email_verified_at: (...)
id: 13
name: "Joseph WhatNot"
phone: "0834602415"
photo: "user.png"
profile: Object
address: "2nd Street↵Hillside"
bio: "Some info here"
course: (...)
created_at: "2018-10-03 06:44:50"
dob: "21 feb 2000"
gender: "male"
id: 2
id_number: "93444245556"
phone: null
updated_at: "2018-10-03 06:44:50"
user_id: 13
@simangae did it work what i wrote you? Can you try user.bio?
@petritr
return response()->json(User::all()->with('profile')->get());
Returns "Method Illuminate\Database\Eloquent\Collection::with does not exist.",…}
But when I change it to
return response()->json(User::with('profile')->get());
it's working but I stilll can't access profile props
@simangae - Sorry to be a pain the console.log didnt really help as it lost the structure. Can you change console.log to
console.log(JSON.stringify(data));
Make sure you include the full content from the console.log, including any brackets.
I would also keep your return User::with('profile')->latest()->get();. I don't think this is the issue as your backend doesn't look like the problem
@simangae what happens when you the following?
<tr v-for="user in users)">
<td>{{ user.name }}</td>
<td>{{ user.profile.bio}}</td>
</tr>
@simangae check now
@D9705996
[{"id":13,"name":"Joseph WhatNot","email":"[email protected] ","email_verified_at":null,"phone":"0834602415","type":"admin","photo":"user.png","created_at":"2018-10-03 06:44:50","updated_at":"2018-10-03 06:44:50","profile":{"id":2,"user_id":13,"phone":null,"dob":"21 feb 2000","id_number":"93444245556","gender":"male","course":"MCA","address":"2nd Street\nHillside","bio":"Some info here","created_at":"2018-10-03 06:44:50","updated_at":"2018-10-03 06:44:50"}}]
@simangae what happens when you do this:
<table class="table dashboard">
<tr v-for="user in users)">
<td>{{ user.name }}</td>
<td>{{ user.profile.bio}}</td>
</tr>
</table>
@petritr Gives an error expected to have v-bind:key
@petritr it's the error in the editor.. with and red underline
@simangae can you past all the vue component code here ? This must work, maybe you have another error too.
@simangae - Thank you for the data it really helps. I confirms you are getting an array of users back from the API
Below shows that HTML and VueJS code that should work
<tr v-for="user in users" :key="user.id">
<td></td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.phone }}</td>
<td>{{ user.photo }}</td>
<td>{{ user.profile.bio}}</td>
<td>
<a href="">
<i class="material-icons">mode_edit</i>
</a>
<a href="">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
new Vue({
el: '#app',
data () {
return {
users: []
}
},
mounted () {
axios
.get('/api/user')
.then(response => (this.users = response.data))
}
});
@simangae try this:
<template>
<div class="table-responsive">
<table class="table dashboard">
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>{{ user.profile.bio }}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
data() {
return {
users: [],
}
},
methods: {
read() {
axios.get('/api/users').then(({ data }) => {
//console.log(data)
this.users= data;
})
.catch((err) => console.error(err));
},
},
mounted() {
this.read();
}
}
</script>
@D9705996 ha :) Yes your example will work too, my is a bit cleaner/best practice again :)
Please sign in or create an account to participate in this conversation.