When I try to add courseDatas.title in v-for I get error: courseDatas is null
App.vue
<template>
<div v-for="(courseDatas, index) in courseDatas" :key="index">
{{ index }} - {{ courseDatas }}
</div>
<script>
export default {
data() {
return {
courseDatas: JSON.parse(
document.getElementById("app").getAttribute("course")
),
};
},
};
Result
When I add this:
<template>
<div v-for="(courseDatas, index) in courseDatas" :key="index">
{{ index }} - {{ courseDatas }} {{ courseDatas.title }}
</div>
EDIT
index.blade.php
#extends('layouts.app')
#section('content')
#foreach ($course as $courses)
<div id="app" course="{{$courses}}">
</div>
#endforeach
<script src="{{asset('js/course/app.js')}}"></script>
#endsection
check if the property is not null then render it using v-for and name the current item course
<template>
<template v-if="courseDatas">
<div v-for="(course, index) in courseDatas" :key="index">
{{ index }} - {{ course}}
</div>
<template>
<template>
and avoid to manipulate DOM as you did, define a prop called course as follows :
<script>
export default {
props:["course"],
data() {
return {
courseDatas: this.course
};
},
};
Related
Im making a laravel SPA and I recently learned how to use vue and I know how v-for works for vue using my components. I only know how to loop only in a single table without relation thats why I'm having a difficult time changing it. I have two tables which are news and comments, and this table news hasMany comments in it.
my blade file for now.
#foreach($news->comments as $comment)
<div class="comment" style="background-color: #f6efef;" >
<div class="author-info">
<img src={{"https://www.gravatar.com/avatar/" . md5(strtolower(trim($comment->email))) . "?s=50&d=retro" }} class="author-image" id="image">
<div class="author-name">
<h4>{{$comment->name}} </h4>
<p class="author-time"> {{ date('jS F, Y - g:iA' ,strtotime($comment->created_at)) }}</p>
</div>
</div>
<div class="comment-content">
{{$comment->comment}}
</div>
</div>
#endforeach
your component goes like this in vue2.0
**block.vue**
<template>
<div class="comment" style="background-color: #f6efef;" v-for="comment in
news.comments" >
<div class="author-info">
<img :src="comment.author_image" }} class="author-image" id="image">
<div class="author-name">
<h4>{{ comment.name }} </h4>
<p class="author-time"> {{ comment.time }}</p>
</div>
</div>
<div class="comment-content">
{{ comment.comment }}
</div>
</div>
</template>
<script>
export default {
name: "block",
props: [ "news" ], //or
data() => ({ news: [] })
}
</script>
I'm setting up a new project and want to retrieve data from passed model binding controller show method but output in show view is null
model :
class Content extends Model
{
protected $fillable = ['title','body'];
}
this is my controller :
public function show(Content $content)
{
return view('content.show',compact('content'));
}
this is my index :
#foreach ($content as $item)
<td>
<a class="btn btn-primary" href="{{ route('Content.show',$item) }}">View</a>
</td>
#endforeach
and this is show method that result is null:
<div class="card-header">
{{ $content->title }}
</div>
<div class="card-body">
{{ $content->body }}
</div>
<div class="card-footer">
{{ $content->created_at }}
/div>
i expect have result in show method because everything is okay but there isn't where is my problem ?
Updated :
dd($content)
because you try to get $content while it is $item now :)
<div class="card-header">
{{ $item->title }}
</div>
<div class="card-body">
{{ $item->body }}
</div>
<div class="card-footer">
{{ $item->created_at }}
</div>
I found the answer
I changed the route resource from resource('Content','ContentController') to
resource('content','ContentController') and the problem has been fixed !
i dont know why !
//used to show a list, like what you are trying to do
public function index()
{
$contents = Content::get();
return view('content.index',compact('contents'));
}
//used to show one item
public function show(Content $content)
{
return view('content.show',compact('content'));
}
What you have for you view works if you are looping over multiple content, otherwise you want:
{{ $content->title }}
</div>
<div class="card-body">
{{ $content->body }}
</div>
<div class="card-footer">
{{ $content->created_at }}
</div>```
I'm listing projects and those projects have statuses. First I'm listing the statuses and inside them projects, but this returns all the projects no matter what the status.
With Laravel I could just:
foreach ($projects->where($project->status_id == $status->id) as $project)
but how to do that with Vue?
<div v-for="status in statuses">
{{ status.title }}
<div v-for="project in projects">
{{ project.title }}
</div>
</div>
I also tried
<div v-for="status in statuses">
{{ status.title }}
<div v-for="project in filteredprojects">
{{ project.title }}
</div>
</div>
computed:{
filteredProjects() {
return this.projects.filter(function(project) {
return project.status_id == status.id;
})
}
},
But no luck
Try like this:
<div v-for="status in statuses">
{{ status.title }}
<div v-for="project in projects">
<div v-if="status.id === project.status_id">
{{ project.title }}
</div>
</div>
</div>
If you have set up a relationship between status and projects (as you should since you're using Laravel), you can load the relationship before it ever gets to the Vue component.
Controller
$statuses = Status::where(...your conditions...)->with('projects')->get();
// EDIT: or get all statuses without conditions
$statuses = Status::with('projects')->get();
// EDIT 2: get all statuses with conditional projects
$statuses = Status::with(['projects' => function($query) {
// add your conditions for projects
$query->where('completed', 0);
}])->get();
Vue
<div v-for="status in statuses">
{{ status.title }}
<div v-for="project in status.projects">
{{ project.title }}
</div>
</div>
I am learning Vuejs. I am making a system where users can set a message as favourite.
But i am getting the below error. Any help to resolve would be appreciated.
[Vue warn]: Failed to mount component: template or render function not
defined. found in
---> Favorite Root
Below is my code =>
Favorite.vue
<template>
<span>
<a href="#" v-if="isFavorited" #click.prevent="unFavorite(post)">
<i class="fa fa-heart"></i>
</a>
<a href="#" v-else #click.prevent="favorite(post)">
<i class="fa fa-heart-o"></i>
</a>
</span>
</template>
<script>
export default {
name: 'favorite',
props: ['post', 'favorited'],
data: function() {
return {
isFavorited: '',
}
},
mounted() {
this.isFavorited = this.isFavorite ? true : false;
},
computed: {
isFavorite() {
return this.favorited;
},
},
methods: {
favorite(post) {
axios.post('/favorite/'+post)
.then(response => this.isFavorited = true)
.catch(response => console.log(response.data));
},
unFavorite(post) {
axios.post('/unfavorite/'+post)
.then(response => this.isFavorited = false)
.catch(response => console.log(response.data));
}
}
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
app.js
require('./bootstrap');
window.Vue = require('vue');
/**
* 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.
*/
Vue.component('Favorite', require('./components/Favorite.vue'));
const app = new Vue({
el: '#app'
});
index.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel">
<h3>All Posts</h3>
<hr>
</div>
#forelse ($posts as $post)
<div class="card">
<div class="card-header">
{{ $post->title }}
</div>
<div class="card-body mb-2">
{{ $post->body }}
</div>
#if (Auth::check())
<div class="card-footer mb-2">
<favorite
:post={{ $post->id }}
:favorited={{ $post->favorited() ? 'true' : 'false' }}
></favorite>
</div>
#endif
</div>
#empty
<p>No post created.</p>
#endforelse
{{ $posts->links() }}
</div>
</div>
</div>
#endsection
Try Vue.component('Favorite', require('./components/Favorite.vue').default); with .default at the end.
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/