How to Fetch data using Vue Js laravel - laravel

How do I fetch data using vue js and laravel . I have created vue component and controller.
Here is my database table structure
<script>
export default {
data(){
return {
kudos : []
}
},
created(){
axios.get('./api/kudos')
.then(response => this.kudos = response.data);
}
}
</script>
What I need to do is fetch the database data to blade file using vuejs .
Could someone guide me step by step?
Controller
Vue Component
Blade File

I think you're looking for something like this?
Controller:
public function searchDatabase( Request $request )
{
$foo = DB::table('bar')
->where([
["description", 'LIKE', "%{$request->input('query')}%"]
])
->limit(5)
->get();
return response()->json($foo);
}
YourComponent.vue
<template>
<div id="wrapper">
<div class="input-group">
<input type="text" placeholder="Search database.." v-model="query" v-on:keyup="autoComplete" class="form-control">
</div>
<div class="panel-footer" v-if="results.length">
<table class="table table-sm">
<tr v-bind:key="result" v-for="result in results">
<td> {{ result.description }} </td>
</tr>
</table>
</div>
</div>
</template>
<script>
export default{
data(){
return {
query: '',
url: '/search/blade/route',
results: []
}
},
methods: {
autoComplete(){
this.results = [];
if(this.query.length > 2){
axios.get('/api/kudos', {params: {query: this.query}}).then(response => {
this.results = response.data;
});
}
}
}
}
</script>
search.blade.php
<your-component></your-component>

Add the name of your data in your response
<script>
export default {
data(){
return {
kudos : []
}
},
created(){
axios.get('./api/kudos')
.then(response => this.kudos = response.data.NameOfYourData);
}
}
</script>

Related

Data are not loaded in Edit Form in Vue app

I'm experimenting with Vue.js and Axios with Laravel. I'm using this tutorial where a simple Posts app is build: https://pusher.com/tutorials/laravel-vue-axios. I'm trying to extend this with an Update function. When I'm clicking on the edit button near a Post, the right Id is fetched. But in my Edit form the data of the post aren't loading. What could be the issue?
This is my code in EditPost.vue:
<template>
<form action="" #submit="editPost(post)">
<h4 class="text-center font-weight-bold">Post edit form</h4>
<div class="form-group">
<input type="text" placeholder="title" class="form-control"> {{ post.title }}
</div>
<div class="form-group">
<textarea placeholder="content" class="form-control" v-model="post.content">
</textarea>
</div>
<div class="form-group">
<button :disabled="!isValid" class="btn btn-block btn-primary" #click.prevent="updatePost(post)">Update
</button>
</div>
</form>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
export default {
name: "EditPost",
data() {
return {
post:{}
}
},
created () {
this.fetchData();
},
mounted() {
this.$store.dispatch('fetchPost')
},
methods: {
...mapActions('post', [
'fetchPost',
'updatePost'
]),
updatePost(post) {
this.$store.dispatch('updatePost', post)
},
fetchData: function () {
var _this = this;
// ajax call - then
_this.$store.commit('setData', {
name: 'post',
data: res.data.post
});
}
},
computed: mapGetters([
'posts'
])
}
</script>
This is the code in recources/js/store/actions.js:
fetchPost({commit}, post) {
axios.get(`/api/posts/${post.id}`)
.then(res => {
commit('FETCH_POST', res.data)
}).catch(err => {
console.log(err)
})
},
UPDATE: I've put in extra code.
file Posts.vue:
<template>
<div>
<h4 class="text-center font-weight-bold">Posts</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Content</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="post in posts">
<td>{{post.title}}</td>
<td>{{post.content}}</td>
<td>
<button class="btn btn-info" #click="editPost(post)"><i style="color:white" class="fa fa-edit"></i></button>
<button class="btn btn-danger" #click="deletePost(post)"><i style="color:white" class="fa fa-trash"></i></button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "Posts",
mounted() {
this.$store.dispatch('fetchPosts')
},
methods: {
editPost(post) {
this.$store.dispatch('fetchPost',post)
},
deletePost(post) {
this.$store.dispatch('deletePost',post)
}
},
computed: {
...mapGetters([
'posts'
])
}
}
</script>
file recources/js/store/getters.js:
let getters = {
posts: state => {
return state.posts
}
}
export default getters
file recources/js/store/state.js:
let state = {
posts: []
}
export default state
file recources/js/store/mutations.js:
let mutations = {
CREATE_POST(state, post) {
state.posts.unshift(post)
},
FETCH_POSTS(state, posts) {
return state.posts = posts
},
UPDATE_POST(state, post) {
let index = state.posts.findIndex(item => item.id === post.id)
},
DELETE_POST(state, post) {
let index = state.posts.findIndex(item => item.id === post.id)
state.posts.splice(index, 1)
}
}
export default mutations
You are using post.content, which is coming from your data prop post. I don't see you adding content to post anywhere in your code.
I'm assuming your getter posts is getting the post data from the store.
So maybe you just need to use that instead?
v-model="posts.content">
Without seeing more of your code I cannot tell you exactly what to do. But your main problem is after you update the store value you need to get that value somehow.

Multiselect with Vue and Laravel

I need to implement a multiselect in the view in which I am working, the idea is to have several options selected in the same select. I have tried some components that I found on the web but without good results.
The route and the driver method in Laravel work well.
I have to feed the Multiselect from a method that brings the data
If you can give me a hand it would be great, I leave the code
<template>
<div>
<div class="col-sm-12">
<select class="form-control form-control-line">
<option v-for="coin in coins" :key="coin.id" value="coin.id">
{{ coin.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data () {
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}
My Method in the CoinController
class CoinController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function coinList() {
$coins = Coin::orderBy('rank', 'asc')
->select('id', 'name', 'rank')
->get();
return response()->json($coins);
}
}
the idea is to do this
Multiselect
I used Laravel 5.6 and Vuejs
You can't use basic select tag to show multiple selected value that you get from server.. because it only support to select one option.. if you want to select multiple like your pict, you have to add more library like vue multiselect
<multiselect v-model="value",
:options="coins",
:multiple="true",
:close-on-select="false",
:clear-on-select="false",
:hide-selected="true",
:preserve-search="true",
placeholder="Pick some"
label="name",
track-by="name",
:preselect-first="true" >
<template slot="tag" slot-scope="props">
<span class="custom__tag">
<span>{{ props.option.language }}</span>
<span class="custom__remove"
#click="props.remove(props.option)">
x
</span>
</span>
</template>
</multiselect>
<script>
export default {
data () {
value: [],
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}

Laravel/Vue.js issues

I need help with my code please. I can't figure it out. I'm getting a "TypeError: this.$http is undefined" and it's driving me insane. I trace it to $http, but I have no idea how to fix it. I've just finished my Laravel course, but Vue.js is new to me. Here's is my code:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-body">
<textarea rows="3" class="form-control" v-model="content"></textarea>
<br>
<button class="btn btn-success pull-right" :disabled="not_working" #click="create_post()">
Create a post
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
},
data() {
return {
content: '',
not_working: true
}
},
methods: {
create_post() {
this.$http.post('/create/post', { content: this.content })
.then((resp) => {
this.content = ''
noty({
type: 'success',
layout: 'bottomLeft',
text: 'Your post has been published !'
})
console.log(resp)
})
}
},
watch: {
content() {
if(this.content.length > 0)
this.not_working = false
else
this.not_working = true
}
}
}
</script>
I think you have a error in submitting the post request.
you need to learn about axios.
Try this example.
axios.post('/create/post', this.content).then((response) => {
// do something
})
npm install axios --save
Add Axios to your Vue.js project, you have to import it:
<script>
import axios from 'axios';
export default {
data() {
return {
posts: [],
errors: []
}
},
created() {
let payload={
content:this.content
}
axios.post('/create/post',payload)
.then(response => {
this.posts = response.data
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>

VueJs component: can't attribute axios reponse to a component variable

I am new to VueJs with Laravel. I have a component called Event in which a 'read more...' link shoud trigger a function that fetch the event infos from the data base and store the in a variable withing this same component.
Here is the code for my component:
<template>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h5>
Title: {{ event.event_name }}
<span class="pull-right">
#click=getEventInfo(event.id)>Read more ...</a></span>
</h5>
<h5>publised by: {{ event.user.name }}
<span class="pull-right" v-text="timeFromNow(event.created_at)"></span>
</h5>
</div>
<div class="panel-body">
<p>{{ event.event_detail }}</p>
</div>
<div class="panel-footer">
<p>
<span>Event for: {{ event.event_to_whom }}</span>
<span>When: {{ dayOfDate(event.event_when_date) }} {{ event.event_when_date }} at {{event.event_when_time}}</span>
</p>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
export default {
name: 'app-event',
props:['event'],
data() {
return {
eventInfo: {}
}
},
methods: {
timeFromNow(tmp) {
return moment(tmp).fromNow();
},
dayOfDate(d) {
let dt = moment(d, "YYYY-MM-DD");
return dt.format('dddd');
},
//event.id
getEventInfo(id){
let url = 'events/' + id;
axios.get(url)
.then((response) => {
console.log(response.data); //returns data
this.eventInfo = response.data;
console.log(this.eventInfo);//returns data
});
console.log(this.eventInfo); //returns nothing
}
}
}
</script>
The problem is when I click the 'read more...' link axios returns a response that I can check using console.log(response.data). Hovever when I console.log(this.eventInfo) outside the axios closure, it returns and ampty object.
Am I doing something wrong? Sorry if the question is too basic.
Thanks
L.B
You are printing logging the property before it is assigned a value.
The code below should resolve any errors
import moment from 'moment';
export default {
name: 'app-event',
props:['event'],
data() {
return {
eventInfo: {}
}
},
methods: {
timeFromNow(tmp) {
return moment(tmp).fromNow();
},
dayOfDate(d) {
let dt = moment(d, "YYYY-MM-DD");
return dt.format('dddd');
},
//event.id
getEventInfo(id){
let url = 'events/' + id;
axios.get(url)
.then((response) => this.handleResponse(response.data));
},
handleResponse(eventInfo) {
console.log(eventInfo);
// do something with the eventInfo...
}
}
Your axios call is asynchrone so your outside console.log will be process before the return of the response.
Just keep your code in the .then((response) => { // here i proceed the read more }

Sorting and Filtering ajax data using Laravel and VueJs

Current code is sorting and filtering data using vue.js. It is working fine but data is dummy, it is hardcoded. I need to get data dynamically from table using vue js and laravel. How can I get dynamic data in gridData?
JS
Vue.component('demo-grid', {
template: '#grid-template',
props: {
data: Array,
columns: Array,
filterKey: String
},
data: function () {
var sortOrders = {}
this.columns.forEach(function (key) {
sortOrders[key] = 1
})
return {
sortKey: '',
sortOrders: sortOrders
}
},
methods: {
sortBy: function (key) {
this.sortKey = key
this.sortOrders[key] = this.sortOrders[key] * -1
}
}
})
// bootstrap the demo
var demo = new Vue({
el: '#app',
data: {
searchQuery: '',
gridColumns: ['name', 'power'],
gridData: [
{ name: 'Chuck Norris', power: Infinity },
{ name: 'Bruce Lee', power: 9000 },
{ name: 'Jackie Chan', power: 7000 },
{ name: 'Jet Li', power: 8000 }
]
}
})
laravel.blade.php
#extends('layouts.app')
#section('title', 'Customers List')
#section('styles')
#endsection
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Customers List</div>
<div class="panel-body">
<script type="text/x-template" id="grid-template">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th v-for="key in columns" #click="sortBy(key)" :class="{active: sortKey == key}">#{{key | capitalize}}<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="entry in data | filterBy filterKey | orderBy sortKey sortOrders[sortKey]">
<td v-for="key in columns">
#{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<div id="app">
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
<demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery"></demo-grid>
</div>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
<script src="/js/vue.js"></script>
<script src="/js/vue-resource.min.js"></script>
<script src="/js/customers.js"></script>
#endsection
You will need to do a few things.
First, in Laravel, create a new route in your routes.php file, for ex.:
Route::get('/api/fighters', 'SomeController#index');
Then in your controller (somecontroller.php), you will have a method index which will query your database table and return it as JSON data.
public function index() {
//query your database any way you like. ex:
$fighters = Fighter::all();
//assuming here that $fighters will be a collection or an array of fighters with their names and power
//when you just return this, Laravel will automatically send it out as JSON.
return $fighters;
}
Now, in Vue, your can call this route and grab the data. Using AJAX. You can use any AJAX library that you like, even jQuery. I currently use Superagent.js. Vue will work just fine with any.
So, in your Vue code, create a new method to get your data.:
methods: {
getDataFromLaravel: function() {
//assign `this` to a new variable. we will use it to access vue's data properties and methods inside our ajax callback
var self = this;
//build your ajax call here. for example with superagent.js
request.get('/api/fighters')
.end(function(err,response) {
if (response.ok) {
self.gridData = response.body;
}
else {
alert('Oh no! We have a problem!');
}
}
}
}
Then you can just call this new method using a button or anyway you like. For example, using a button click event:
<button type="button" #click="getDataFromLaravel">Get Data</button>
Or you can even just have the data loaded automatically using Vue's ready function:
// bootstrap the demo
var demo = new Vue({
el: '#app',
data: {
.... }
ready: function () {
this.getDataFromLaravel();
},
methods: {
.... }
});
Done! You now have your database data assigned to Vue's data property gridData.

Resources