Search code examples
vue.jsvuetify.js

vuetify v-data-table-server not showing data from server


I'm rather new to vue and vuetify. I'm trying to display data retrieved from as server. The table shows, the table headers are correct. The requests to the server gets done and an array is returned. I then assign the json array in the response to serverItems and nothing happens. The loading animation also never turns back off. My guess is I'm doing something wrong related to reactivity or variable scoping, but I cannot figure it out.

In my table I have:

 <v-data-table-server :headers="headers"
                      :items="serverItems"
                      :items-length="totalItems"
                      :loading="loading"
                      item-value="Platform"
                      @update:options="loadItems"></v-data-table-server>

in my script I have:

<script setup>
    import { ref } from 'vue'
    let loading = false;
    let itemsPerPage = 20;
    const headers = [
        {
            title: 'Platform',
            align: 'start',
            sortable: false,
            key: 'Platform',
        },
        { title: 'Title', key: 'Title', align: 'end' },
        { title: 'Release Date', key: 'Release Date', align: 'end' },
        { title: 'Publisher', key: 'Publisher', align: 'end' },
        { title: 'Developer', key: 'Developer', align: 'end' }
    ];
    const serverItems = [];
    let totalItems = 1;

    const loadItems = async ({ page, itemsPerPage, sortBy }) => {
        loading = true

        fetch('https://localhost:7201/api/data/GetItems', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                page: page,
                itemsPerPage: itemsPerPage,
                sortBy: sortBy

            })
        }).then((response) => {
            return response.json();
        }).then((data) => {
            serverItems.push(data);
            totalItems = data.length;
            loading = false;
        }).catch(error => {
            console.error(error);
        });


    }
</script>

The response from server is like:

[
    {
        "Platform": "GameCube",
        "Title": "SSX 3",
        "Release Date": "Oct 21, 2003",
        "Publisher": "Electronic Arts",
        "Developer": "EA Sports",
        "Genre": "",
        "Added Date": "Nov 29, 2020",
        "Value": 13.8,
        "Description": "SSX 3 allows gamers t.....",
        "Release Year": 2003,
        "Series": "SSX"
    },
.....

]

edit 2: Using ref made it work, Seems in my earlier tries is was also using "this" incorrectly making me think that didn't work either. I have some learning to do on vue, this and composition api. As I am new to vue that isn't that strange. for anyone's use, this worked:

const loading = ref(false);
const itemsPerPage = ref(20);
const headers = [
    {
        title: 'Platform',
        align: 'start',
        sortable: false,
        key: 'Platform',
    },
    { title: 'Title', key: 'Title', align: 'end' },
    { title: 'Release Date', key: 'Release Date', align: 'end' },
    { title: 'Publisher', key: 'Publisher', align: 'end' },
    { title: 'Developer', key: 'Developer', align: 'end' }
];
const serverItems = ref([]);
const totalItems = ref(0);

async function loadItems ({ page, itemsPerPage, sortBy }) {
    loading.value = true

    fetch('https://localhost:7201/api/data/GetItems', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            page: page,
            itemsPerPage: itemsPerPage,
            sortBy: sortBy

        })
    }).then((response) => {
        return response.json();
    }).then((data) => {
        serverItems.value = data;
        totalItems.value = data.length;
        loading.value = false;
    }).catch(error => {
        console.error(error);
    });

Solution

  • Try to make your state reactive using ref:

       let loading = ref(false);
        let itemsPerPage = ref(20);
    ...
      const serverItems = ref([]);
      const totalItems = ref(1);
    
     ...
    
    serverItems.value = data
    totalItems.value = data.length;
    loading.value = false;