Laravel blade with Vue component not show data - php

I am using Laravel 5.6 and create model named process and a controller with a function that gets all the records of the model:
public function showProcessList(){
return response()->json(Process::all());
}
In the web.php routes file also defined the route to retrieve the records, it works well, i tested the endpoint and i can see the data:
Route::get('process/list', 'ProcessController#showProcessList');
In a blade file i try to show the list creating a Vue component like this:
<!-- Process List -->
<div class="row">
<process></process>
</div>
<script src='{{ asset("public/js/app.js") }}'></script>
file app.js has this:
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('process', require('./components/Process.vue'));
const app = new Vue({
el: '#app'
});
components/Process.vue contains this:
<template>
<div class="tile mb-4 col-md-6 col-lg-12" id="listProcess">
<div class="page-header">
<h3 class="mb-4 line-head">Process List</h3>
</div>
<div v-for="process in processList">
<p>{{ process.name }}</p>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data () {
return {
processList: [],
}
},
created() {
this.showProcessList();
},
methods: {
showProcessList () {
axios.get('/process/list')
.then(response => {
this.processList = response.body;
});
}
},
}
</script>
Then execute npm run dev and load in web browser the view that invoke the Vue component:
<div class="row">
<process></process>
</div>
<script src='{{ asset("public/js/app.js") }}'></script>
(I have to add public folder to the path of css and js files)
nothing happens, the data doesn't load in the view and i cannot see any error in console.
Testing the endpoint the result is:
[
{
"id": 1,
"created_at": "2018-03-28 04:33:02",
"updated_at": "2018-03-28 04:33:02",
"name": "first_process",
},
]
So, at this point i cannot see where is the error in my code or what i missing?
Thanks.

Related

Why can i not get the Data from my laravel database with vue.js?

I have the following Problem:
I have a table with the names of some companies on a full set up laravel and i want them to be displayed via vue.js
i got the following done with a tutorial but it wont work out as it's intended to. I just get the Table Header.
It has to be solved via the API.
Please help :)
Welcome.vue
<script setup>
import { Head, Link } from '#inertiajs/inertia-vue3';
import axios from 'axios';
</script>
<template>
<Head title="Welcome" />
<div class="body">
<FirmenListe :firmas = "firmas"></FirmenListe>
</div>
</template>
<script>
import FirmenListe from "./FirmenListe.vue"
export default {
name: "App",
components: {
FirmenListe
},
data(){
return{
url: "http://localhost:5174/routes/api.php",
firmas: []
};
},
methods: {
getFirma(){
axios.get(this.url).then(data => {
this.firmas = data.data;
})
}
},
created(){
this.getFirma();
}
}
</script>
FirmenListe.vue
<template>
<div class="firma-liste">
<div class="data">
<table class="ui celled table">
<tr>
<th>ID</th>
<th>Firmenname</th>
</tr>
<body>
<tr>
<Firmen
v-for="firmas in firmas"
:key="firmas.id"
:firmas="firmas"/>
</tr>
</body>
</table>
</div>
</div>
</template>
<script>
import Firmen from "./Firmen.vue";
export default {
name: "FirmenListe",
components: {
Firmen
},
props: {
firmas: {
type: Array
}
}
}
</script>
Firmen.vue
<template>
<td>{firmas.id}</td>
<td>{firmas.firmenname}</td>
</template>
<script>
export default {
name: "firmas",
props: {
firmas: {
type: Object
}
}
}
</script>
routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FirmaController;
use App\Http\Controllers\MitarbeiterController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::resource('firma', 'FirmaController');
Route::resource('mitarbeiter', 'MitarbeiterController');
You call a wrong route
try this :
return{
url: "http://localhost:5174/api/firma",
firmas: []
};
},

Vue2 Laravel component in list

I am building a Laravel app and trying to use vue.js (without much success!). I'm not understanding the way components work with ajax data. Almost all examples I've found showing this functionality define the data for the component at the app level, not the component level.
I'm trying to dynamically define my data in the component itself, and always get the error that Property or method tasks is not defined on the instance but referenced during render. Here's the component, which is meant to just call out to an endpoint to pull basic "to do" tasks:
Vue.component('tasks', {
data: function() {
return {
tasks: []
}
},
mounted() {
this.getTasks();
},
methods: {
getTasks() {
axios.get('/tasks').then(function (response) {
this.tasks = response.data;
console.dir(this.tasks);
})
.catch(function (error) {
console.log(error);
});
}
},
template: `
<div class="card">
<div class="card-title">{{ task.name }}</div>
<div class="card-body">
<div class="service-desc">{{ task.description }}</div>
<div class="task-notes"><input class="form-control" v-model="task.notes" placeholder="Notes"></div>
<div class="task-active"><input type="checkbox" checked data-toggle="toggle" data-size="sm" v-model="task.active" v-on:click="$emit('disable')"></div>
</div>
</div>
`
});
the component is called from within the blade template using:
<tasks v-for="task in tasks" :key="task.id"></tasks>
tasks is declared in the data function, so I'm not sure why vue is telling me it's not defined?
When you define a data property on a component it's only available within that component and its template. Your v-for directive is in the parent scope (i.e outside of the component where tasks is defined).
The simplest solution here is probably to move the container element inside the component, and iterate over the tasks there:
<div>
<div class="card" v-for="task in tasks" :key="task.id">
<div class="card-title">{{ task.name }}</div>
<div class="card-body">
<div class="service-desc">{{ task.description }}</div>
<div class="task-notes"><input class="form-control" v-model="task.notes" placeholder="Notes"></div>
<div class="task-active"><input type="checkbox" checked data-toggle="toggle" data-size="sm" v-model="task.active" v-on:click="$emit('disable')"></div>
</div>
</div>
</div>
Note: you can't use v-for a template's root element, which is why you'd move the container element into the template.
An alternative is break this into two components (e.g. TaskList and TaskItem) where the parent component is responsible for fetching the tasks from the API. The child component can just receive a single task as a prop and render it to the UI.
TaskList
Vue.component('task-list', {
data: function() {
return {
tasks: []
}
},
mounted() {
this.getTasks();
},
methods: {
getTasks() {
axios.get('/tasks').then(response => {
this.tasks = response.data;
console.dir(this.tasks);
})
.catch(error => {
console.log(error);
});
}
},
template: `
<div class="container">
<task-item
v-for="task in tasks"
:key="task.id"
:task="task"
/>
</div>
`
});
TaskItem
Vue.component('tasks', {
props: {
task: {
required: true
}
},
template: `
<div class="card">
<div class="card-title">{{ task.name }}</div>
<div class="card-body">
<div class="service-desc">{{ task.description }}</div>
<div class="task-notes"><input class="form-control" v-model="task.notes" placeholder="Notes"></div>
<div class="task-active"><input type="checkbox" checked data-toggle="toggle" data-size="sm" v-model="task.active" v-on:click="$emit('disable')"></div>
</div>
</div>
`
});
The advantage of this is that it separates the responsibility of the components a little better. You could add logic to the TaskList component to handle displaying a loading spinner and/or error messages for the API call, while TaskItem only has to concern itself with displaying a single task.

Registering a 2nd component? Vue.js Laravel6

I have created a fresh Laravel6 project to work out how to register components...
I have cloned ExampleComponent.vue to ExampleComponent2.vue
// ExampleComponent2.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example2 Component</div>
<div class="card-body">
I'm an example2 component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component2 mounted.')
}
}
</script>
// app.js
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('example-component2', require('./components/ExampleComponent2.vue').default);
// login.blade.php
- I have placed this under the closing tag and #endsection to test on the login page...
<example-component2></example-component2>
I have run "npm run watch" in command line and there are no error messages...
When I load the login route, I open the console to see this error message?
[Vue warn]: Unknown custom element: - did you
register the component correctly? For recursive components, make sure
to provide the "name" option.
(found in )
How do I register extra components???
// login.blade.php - I have placed this under the closing tag and #endsection to test on the login page...
You need an element with the id that you defined in your js/app.js:
const app = new Vue({
el: '#app', // you need an element with id="app". Your vue component will replace this
});
Then put your component inside that element.
//login.blade.php
#extends('layouts.authentication')
#section('content')
<div id="app">
<example-component2/>
</div>
#endsection

How to combine laravel and vue routes

I am creating a simple laravel and vuejs CRUD Application. Vue Routes are not working, I am pretty new to vuejs; please see the code
Below is the code for web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/vue','Api\PostController#home');
Route::resource('/api','Api\PostController');
Following is the code for app.js
require('./bootstrap');
window.Vue = require('vue');
window.VueRouter=require('vue-router').default;
window.VueAxios=require('vue-axios').default;
window.Axios=require('axios').default;
let AppLayout = require('./components/App.vue');
const Posts = Vue.component('Posts',require('./components/Posts.vue'));
const EditPost =
Vue.component('EditPost',require('./components/EditPost.vue'));
const AddPost =
Vue.component('AddPost',require('./components/AddPost.vue'));
const DeletePost =
Vue.component('DeletePost',require('./components/AddPost.vue'));
const ViewPosts =
Vue.component('ViewPosts',require('./components/ViewPosts.vue'));
const ExampleComponent =
Vue.component('ViewPosts',require('./components/ExampleComponent.vue'));
// Registering routes
Vue.use(VueRouter,VueAxios,axios);
const routes = [
{
name: 'Posts',
path: '/posts',
component: Posts
},
{
name: 'AddPost',
path: '/add-posts',
component: AddPost
},
{
name: 'EditPost',
path: '/edit-post/:id',
component: EditPost
},
{
name: 'DeletePost',
path: '/delete-post',
component: DeletePost
},
{
name: 'ViewPosts',
path: '/view-post',
component: ViewPosts
},
{
name: 'ExampleComponent',
path: '/example-component',
component: ExampleComponent
},
];
const router = new VueRouter({mode: 'history', routes: routes});
new Vue(
Vue.util.extend(
{ router },
AppLayout
)).$mount('#app');
This is the code of my blade tamplate, when I browse http://localhost:8000/vue this view is being rendered. As you can see in the web.php code above.
I can also see the notification in console You are running Vue in development mode. Make sure to turn on production mode when deploying for production.
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<header class="page-header">
<div class="branding">
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
<h1>Vue.js CRUD With Laravel 5 application</h1>
</div>
</header>
</div>
<section id="app">
</section>
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
But when I run my application using
php artisan serve
and browse to
http://localhost:8000/posts
Application show a 404 error. Please help me with this problem.
You need to add a laravel route for the view where you are using the app.js (vuejs) in routes/web.php file.
Route::get('/route-name/?{name}', function(){
return redirect('vue_app');
})->where('name', '[A-Za-z]+');
and then you have to use the laravel route as a parent route for the vuejs's routes and use the url like below,
http://localhost:8000/laravel-route/view-route
in your case,
http://localhost:8000/route-name/posts
Or you can also use,
Route::get('{any}', function () {
return view('vue_app');
})->where('any', '.*');
and instead of previous use localhost:8000/posts
Try this to your web.php route
Route::get('/', function () {
return view('index');
});
Route::get('/{catchall?}', function () {
return response()->view('index');
})->where('catchall', '(.*)');
if with {any} did not work, you may also try adding ?
Route::get('/any-your-route/{any?}', function() {
return view('your-view');
})->where('any', '.*');
hope this help you. i just try this code and work on laravel blade template with vue router.
Tested on Laravel 8
For your second part of question,
You should use <div> instead of <section> and you have to bring the main/registered component inside of the html element selected by id="app" in blade file. in your case,
<div id="app">
<app-layout></app-layout>
</div>
Hope this help you. you can check this basic vuejs with laravel
PS: You should ask two different problem in two seperate posts.
you can do simply like this.
Route::get('/{vue_capture?}', function(){
return view('welcome');
})->where('vue_capture', '[\/\w\.-]*');

data received from laravel controller not updating to vue variable

I am creating a web app having dashboard using laravel and vue.
When I pass data from controller to vue file data is received properly but when I set it to vue variable the value is not set in the variable. All data is received and its displayed in the console but when I set it to the vue variable, the variable doesn't update its value.
This is my Controller class:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UsersController extends Controller
{
//
public function index()
{
$users=User::all();
return response()->json($users);
}
}
This is myTeam.vue for receiving and displaying the data:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card card-default">
<div class="card-header">Example Component</div>
<h1>
This request list
Hello,{{this.items}}
</h1>
<ul class="list-group">
<li class="list-group-item" v-for="t in items">{{items}}</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
//items: []
items:[],
}
},
created() {
var self=this;
axios.get('/allusers').then((response) => self.items=response.data) .catch((error)=>console.log(error));
axios.get('/allusers') .then(response => console.log(response.data));
console.log('Component mounted.'+this.items)
},
}
</script>
Now when I run it the console prints the array properly means data is received but when I set it to items variable the data is not set.
My Output is this:
This is the output image file
Please check it and thanks in advance ...
This is never print items array because it's execute before the ajax response is filled.
console.log('Component mounted.'+this.items)
That's why your console is always blank. You can search about blocking and non blocking programming.
your code have small bug. Update your code and try this:
<h1>
This request list
Hello,{{items}}
</h1>
<ul class="list-group">
<li class="list-group-item" v-for="t in items">{{t}}</li>
</ul>
...
<script>
export default {
data(){
return {
items:[],
}
},
mounted: function () {
this.getList();
}
methods: {
let _this = this;
axios.get('/allusers')
.then((response) => _this.items = response.data)
.catch((error)=>console.log(error));
},
}
</script>
This can help you. Good luck.

Categories