In this lesson, we will create a dropdown select to pick from a list of categories. For this, we will create a new composable and a new API endpoint with the API Resource.
Let's start this lesson by creating a Controller with the API route.
php artisan make:controller Api/CategoryControllerphp artisan make:resource CategoryResource
app/Http/Controllers/Api/CategoryController.php:
use App\Http\Resources\CategoryResource; class CategoryController extends Controller{ public function index() { return CategoryResource::collection(Category::all()); }}
routes/api.php:
use App\Http\Controllers\Api\CategoryController; Route::get('posts', [PostController::class, 'index']);Route::get('categories', [CategoryController::class, 'index']);
In the Resource, we will only add the id
and name
fields.
app/Http/Resources/CategoryResource.php:
class CategoryResource extends JsonResource{ public function toArray(Request $request): array { return [ 'id' => $this->id, 'name' => $this->name, ]; }}
Now that we have an API endpoint, we can create a new Composable and use it to get the categories. The composable for the categories is going to be almost identical to the one that we have for the posts.
resources/js/composables/categories.js:
import { ref } from 'vue' export default function useCategories() { const categories = ref({}) const getCategories = async () => { axios.get('/api/categories') .then(response => { categories.value = response.data.data; }) } return { categories, getCategories }}
Next, we need to add categories Composable to the PostsIndex
Vue component and show all the categories in the select input above the table.
resources/js/components/Posts/Index.vue:
<template> <div class="overflow-hidden overflow-x-auto p-6 bg-white border-gray-200"> <div class="min-w-full align-middle"> <div class="mb-4"> <select v-model="selectedCategory" class="block mt-1 w-full sm:w-1/4 rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"> <option value="" selected>-- Filter by category --</option> <option v-for="category in categories" :value="category.id" :key="category.id"> {{ category.name }} </option> </select> </div> // ... </div> </div></template> <script setup>import { onMounted, ref } from "vue";import { TailwindPagination } from 'laravel-vue-pagination';import usePosts from "@/composables/posts";import useCategories from "@/composables/categories"; const selectedCategory = ref('') const { posts, getPosts } = usePosts()const { categories, getCategories } = useCategories() onMounted(() => { getPosts() getCategories() })</script>
After visiting the page you should see the select list.
You have added this line as a new line const 'selectedCategory = ref('')'... And you missed highlighting it... I assume povillas did not do that mistake, may be some of his team member did... But please keep in mind for a new learner like me, it becomes so much annoying... Please do not ignore these little things
Thanks for the report. Don't forget that we are all humans and make mistakes :) look at it this way, you get an error or something doesn't work then you debug, it's a learning process! ;) good luck learning.
Yes, in fact I was thinking that maybe all the things you dont mention in the course is to force us find the solution ourselves so we can grasp better the key concepts and little traps of the development process. Thanks guys. Great work.
Could you please help with this error Uncaught (in promise) ReferenceError: ref is not defined
Sorry :) I miss this part " import { onMounted, ref } from "vue"; "