John Davidson

php - How to use one method to show a view and the same method to return resource collection Laravel/Vue

0 comments
Message:


I have a Vue component that uses Laravel Api data to show in the template. I have a CustomerController which uses the index() method to return the collection of CustomerResource which I used to create the API. I need that method also to show the view. How do I show the index.blade.php when the index method of CustomerController is used for API. If u have any questions about this problem ask me in the comment.


Customer Controller


   public function index() {
return CustomerResource::collection(Customer::all());
}

api.php


    Route::middleware('api')->prefix('v1')->group(function() {
Route::apiResource('/customers', CustomerController::class);
});

index.blade.php


    @extends('layouts.app')

@section('content')
<all-customers></all-customers>
@endsection

AllCustomers.vue


    <template>
<div class="customers">
<div class="main-panel">
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-xl-12 text-right">
<a href="#">
<!-- <router-link class="btn" :to="{ name: 'AddCustomer'}">Add New</router-link > -->
</a>
<a href="#">
<button class="btn">Import</button>
</a>
<!-- <downloadExcel class = "btn btn-default"
:data = "json_data"
:fields = "json_fields"
worksheet = "My Worksheet"
name = "customers.xls">
Export
</downloadExcel> -->
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header card-header-primary">
<h4 class="card-title ">All Customers</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead class=" text-primary">
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Address</th>
<th>Actions</th>
</thead>
<tbody>
<tr v-for="(customer,index) in customers" :key="index">
<td>
{{ customer.id }}
</td>
<td>
{{ customer.name }}
</td>
<td>
{{ customer.email }}
</td>
<td>
{{ customer.phone }}
</td>
<td>
{{ customer.address }}
</td>
<!-- <td>
<router-link :to="{name: 'EditCustomer'}">
<span class="material-icons">edit</span>
</router-link>
<span class="material-icons">delete</span>
</td> -->
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
import JsonExcel from 'vue-json-excel'
export default {
name:'AllCustomers',
components:{
downloadExcel: JsonExcel
},
data(){
return{
customers:[],
}
},
mounted(){
axios
.get('http://localhost:8000/api/v1/customers')
.then(response=> this.customers = response.data.data)
}
}
</script>


My Answer:
To achieve this, you can modify your CustomerController's index() method to return the view if the request is not an API request. Here's how you can do it:

php
use App\Customer;
use App\Http\Resources\CustomerResource;
use Illuminate\Http\Request;

public function index(Request $request) {
$customers = Customer::all();

if ($request->wantsJson()) {
return CustomerResource::collection($customers);
}

return view('customers.index', compact('customers'));
}


In this updated index() method, we first fetch all customers from the database. Then, we check if the request wants JSON response using the `$request->wantsJson()` method. If it does, we return the collection of customers as CustomerResource. If not, we return the view 'customers.index' and pass the customers collection to the view using the `compact()` function.

Now, when you make a request to the API endpoint `/api/v1/customers`, it will return the JSON response. And when you access the route in the browser, it will render the `index.blade.php` view with the customers data.

Make sure to update your Vue component to handle the API response correctly and display the data in the template.

Rate this post

4 of 5 based on 4742 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us