0

I have a vue 3 component in Laravel 10 in which i'm applying vue3-carousel.

Component Infor: I'm creating a dynamic team members carousal where i can show team of a company with dynamic bar of team category. It's all working fine.

Issue: In my category bar where all the dynamic categories are coming from database Except from the All cateory which i created manually(not add in database) .category bar iamge

All my dynamic categories are working fine. when i click on them it filled the carousel with respective data. The issue is with the All category i'm getting the following error and warnings .

Error:

TeamMembers.vue:30 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'id')
at TeamMembers.vue:30:69
at renderList (chunk-AR356GSD.js?v=ae36e8ac:3417:18)
at TeamMembers.vue:60:29
at renderFnWithContext (chunk-AR356GSD.js?v=ae36e8ac:2039:17)
at Proxy.<anonymous> (vue3-carousel.js?v=ae36e8ac:561:102)
at renderComponentRoot (chunk-AR356GSD.js?v=ae36e8ac:2068:39)
at ReactiveEffect.componentUpdateFn [as fn] (chunk-AR356GSD.js?v=ae36e8ac:5342:26)
at ReactiveEffect.run (chunk-AR356GSD.js?v=ae36e8ac:1248:23)
at instance.update (chunk-AR356GSD.js?v=ae36e8ac:5389:52)
at updateComponent (chunk-AR356GSD.js?v=ae36e8ac:5236:18)

It's api response data is also not coming correctly , it just give the data for the second category(Leadership) when i click on All

API Response: 
 {members: {…}}
   members: 
    current_page:1
    data:Array(3)
      0:{id: 2, name: 'Maham Hassan', role: 'CTO Founder', profile_picture: 'images/leaderShip_pic1.png', twitter_link: 'https://www.salesforce.com/in/?ir=1', …}
      1:{id: 11, name: 'alan', role: 'Dev', profile_picture: 'images/team5.png', twitter_link: null, …}
      2:{id: 1, name: 'Maham Hassan', role: 'CTO Founder', profile_picture: 'images/leaderShip_pic1.png', twitter_link: null, …}
     length:3
     [[Prototype]]:Array(0)
     first_page_url:"http://127.0.0.1:8000/our-team/All?page=1"
     from:1
     last_page:4
     last_page_url:"http://127.0.0.1:8000/our-team/All?page=4"
     links:(6) [{…}, {…}, {…}, {…}, {…}, {…}]
     next_page_url:"http://127.0.0.1:8000/our-team/All?page=2"
     path:"http://127.0.0.1:8000/our-team/All"
     per_page:3
     prev_page_url:null
     to:3
     total:11
     [[Prototype]]:Object
     [[Prototype]]:Object

Warning Image: warning

What I simply want is that when i click on All it should load all the data or results in carousel like other dynamic categories. But it's not fetching the data and showing it.

Component Code: TeamMember.vue

<template>
    <div>
        <!-- Category Section -->
        <div class="isotop_nav" id="categories-container">
            <ul>
                <li>
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === null }"
                        @click.prevent="handleCategoryClick(null)">
                        All
                    </a>
                </li>
                <!-- Loop through categories and generate links -->
                <li v-for="category in categories" :key="category.id">
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === category.name }"
                        @click.prevent="handleCategoryClick(category.name)">
                        {{ category . name }}
                    </a>
                </li>
            </ul>
        </div>

        <!-- Team Section -->
        <div class="leadership_list onTeam_sec">
            <div  id="filtered-team-members">
            <carousel :items-to-show="3" :items="members"  class="row justify-content-center">
                    <!-- Use Vue data properties and methods -->
                    <!-- console members data -->


                    <slide v-for="(member) in members" :key="member.id" class="col-xxl-3 col-xl-3 col-lg-4 col-md-4 category-item">
                        <div :data-category="member.category ? member.category.name : ''" >
                            <div class="leadership_list_info">
                                <span>
                                    <img :src="`/uploads/${member.profile_picture}`" alt="leadership profile" />
                                </span>
                                <a href="#"><strong>{{ member.name }}</strong></a>
                                <p>{{ member . role }}</p>
                                <div class="contactSocial_infoList">
                                    <ul>
                                        <!-- Use Vue data properties -->
                                        <li v-if="member.twitter_link">
                                            <a :href="member.twitter_link" target="_blank" class="s_tw">
                                                <i class="fa-brands fa-twitter"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.salesforce_link">
                                            <a :href="member.salesforce_link" target="_blank" class="s_inst">
                                                <i class="fa-brands fa-salesforce"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.linkedIn_link">
                                            <a :href="member.linkedIn_link" target="_blank" class="s_link">
                                                <i class="fa-brands fa-linkedin"></i>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </slide>
                    <!-- <Page :total="pageInfo" :current="pageInfo.current_page"  :page-size="parseInt(pageInfo.total)" v-if="pageInfo"/> -->
                    <!-- <p v-if="members.length === 0">No team members found.</p> -->
                    <template #addons>
                        <navigation />
                        <pagination />
                    </template>
                </carousel>
            </div>
        </div>
    </div>
</template>


<script>
    import axios from "axios";
    import 'vue3-carousel/dist/carousel.css'
    import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel'
    // import ViewUIPlus from 'view-ui-plus'
    // import 'view-ui-plus/dist/styles/viewuiplus.css'


    export default {
        data() {
            return {
                 members: [],
                //     members: [
                //     { id: 1, name: 'John Doe', role: 'Developer', twitter_link: 'https://twitter.com/johndoe' },
                //     { id: 2, name: 'Jane Doe', role: 'Designer', linkedIn_link: 'https://linkedin.com/janedoe' },
                // ],
                categories: [],
                selectedCategory: null,
                // currentPage: 1,
                // itemsPerPage: 3,  // Adjust as needed
                // totalItems: 0,
                // total: 3,
                // pageInfo: null,
            };
        },
        components: {
            // VueAwesomePagination,
            Carousel,
            Slide,
            Pagination,
            Navigation,
            // ViewUIPlus
        },
        mounted() {
            // Fetch initial team members (all members)
            //
            this.fetchCategories();

            // this.filterTeamMembers();
        },
        methods: {

            // function to fetch categories
            fetchCategories() {
                // axios.get(`/our-team/categories?page=${page}&total=${this.total}`)
                // axios.get(`/our-team/categories`)
                axios.get(`/our-team/categories`)
                    .then(response => {
                        console.log('API Response for categories:', response.data);
                        this.categories = response.data.categories;
                        this.members = response.data.members;
                        // this.members = Object.entries(response.data.members).map(([key, value]) => value);
                        console.log(this.members);
                        // this.pageInfo = response.data.members;
                        // console.log(this.pageInfo);
                        this.selectedCategory = null;
                    })
                    .catch(error => {
                        console.error('Error fetching categories:', error);
                    });
            },

            // Function to fetch and display filtered team members
            filterTeamMembers(member ) {
                 const endpoint = member ? `/our-team/${member}` : '/our-team/all';
                axios.get(endpoint)
                    .then(response => {
                        console.log('API Response:', response.data);
                        // this.members = response.data.members;
                        this.members = response.data.members;
                        // this.totalItems = response.data.total;
                    })
                    .catch(error => {
                        console.error('Error fetching team members:', error);
                    });
            },

            handleCategoryClick(category) {
                // Set the selected category
                this.selectedCategory = category;
                // this.currentPage = 1;
                // Filter team members based on the selected category
                 this.filterTeamMembers(category);
            },
        },

    }
</script>

Route

Route::get('/our-team/{member?}', [TeamMemberContentController::class, 'filterByCategory'])->name('team-members.filter');

Controller Code: TeamMemberController.php

    public function filterByCategory(Request $request, $category)
    {
        // Log::info('Received category:', ['category' => $category]);
        if ($category === 'all' || $category === null) {
            // If the category is 'all', return all team members
            $members = TeamMember::where('status', 'opened')->orderBy('order_column')->paginate(3);
        } else {
            // If it's a specific category, filter by that category
            $categoryModel = TeamCategory::where('name', 'like', $category)->first();

            if (!$categoryModel) {
                // Handle the case when the category is not found
                return response()->json([
                    'members' => []
                ]);
            }

            // $members = $categoryModel->teamMembers;
            $members = $categoryModel->teamMembers()->where('status', 'opened')->orderBy('order_column')->get();
        }

        if ($request->ajax()) {
            return response()->json([
                'members' => $members,
                // 'categories' => $categories,
                // 'selectedCategory' => $selectedCategory,
            ]);
        }

        return view('our-team.our-team', compact('members', 'categories'));
    }

Tell me how to resolve this issue and how to handle the data fetching for All category.

Tried: I tried to fetch all the data on All category when i select it but it's giving error.

Expect: Just like the other dynamic categories are working what i want is that when i click on it should fetch all the data.

4
  • Post the error messages as text, not images. Does the PHP give the correct result? You should narrow down scope of question Commented Dec 31, 2023 at 17:56
  • Realize the template code is executed on component mounting, and the fetch for categories data begins at the same time, but being an async operation the result will not be available for some X amount of time. What will the template do when it encounters v-for="category in categories" :key="category.id" when categories is initially empty [] and it needs to access id property of array object that doesn't exist? It gives you your error "Cannot read properties of null (reading 'id')". You should not render this code until categories is non-empty, e.g. v-if="categories.length > 0" Commented Dec 31, 2023 at 18:54
  • hello @yoduh , i tried to add the All from the database dynamically and then try to fetch but it is still giving the same error . @yoduh , how can i then fetch all the team members . because i just want that when i click on All it should show me all the team members. Commented Dec 31, 2023 at 19:01
  • hello @user3783243 , i edit the question and add both the error text and api response it is also not coming right the response data. It just fetch the first dynamic category values. Commented Dec 31, 2023 at 19:02

1 Answer 1

2

You are using ->get() when a category clicked, and ->paginate(3) when getting all of them.

This cause a pagination in where getting all, so use this.members = response.data.members.data; when getting all of them and this.members = response.data.members; when a category clicked in vue,

or change ->paginate(3) to ->get() where getting all of them in Controller like getting category members, or what you preferr.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks alot man. I'm really grateful to you and the stack overflow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.