Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Alexb0903's avatar

Vue component not updating

Hi everyone, I'm currently trying to update my table with an excel sheet that the user will upload via an input file button.

Im a using the SheetJS tool. The file is read correctly as the headers results give (the one on my excel file)

20) ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "101", "105", "11", "12", "13", "14", "15", "17", "201", "302"]

but for some reason the headers variable doesn't update when it receive the new data even when it's hardcoded . Here is my component

<template>
    <div>
        <h1>Ajouter un fichier</h1>
        <input type="file" @change="processFile($event)">
        <h2></h2>
        <table class="table-striped table-hover table-responsive">
            <thead>
            <tr>
                <th v-for="item in headers">{{item}}</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="item in tickets">
                <td v-for="key in item">
                    <label>{{key}}</label>
                    <p>{{item.key}}</p>
                </td>
            </tr>
            </tbody>
            <tfoot></tfoot>
        </table>
    </div>

</template>

<script>
    import * as XLSX from "xlsx";

    export default {
        data() {
           return {
               tickets: [{name:"test"}],
               headers: 'Allo'
           }
        },
        mounted() {
            console.log('Component mounted.')
        },

        methods: {
            processFile(event) {
                var files = event.target.files, i, f;
                for (i = 0, f = files[i]; i != 1; ++i) {
                    var reader = new FileReader(),
                        name = f.name;
                    console.log(f.name);
                    reader.onload = function(e) {
                        var results,
                            data = e.target.result,
                            fixedData = fixdata(data),
                            workbook=XLSX.read(btoa(fixedData), {type: 'base64'}),
                            firstSheetName = workbook.SheetNames[0],
                            worksheet = workbook.Sheets[firstSheetName];
                        console.log(get_header_row(worksheet));
                        this.headers=get_header_row(worksheet);
                        results=XLSX.utils.sheet_to_json(worksheet);
                        console.log(results);
                        this.tickets=results;
                    };
                    reader.readAsArrayBuffer(f);
                }

            }
        }
    }
    function get_header_row(sheet) {
        var headers = [], range = XLSX.utils.decode_range(sheet['!ref']);
        console.log(headers);
        var C, R = range.s.r; /* start in the first row */
        for(C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
            var cell = sheet[XLSX.utils.encode_cell({c:C, r:R})] /* find the cell in the first row */
            var hdr = "UNKNOWN " + C; // <-- replace with your desired default
            if(cell && cell.t) hdr = XLSX.utils.format_cell(cell);
            headers.push(hdr);
        }
        return headers;
    }


</script>

I didnt put the fixdata in the code because it is not the problem.

0 likes
5 replies
Alexb0903's avatar

this.header = get_header_rows seems to be the error but i dont know why. The get_header_rows give me the output that is in my post so why is this.headers not setting ?

mabdullahsari's avatar
Level 16

Welcome to the world of JavaScript!

It's too complicated to explain it in this forum post, but basically the this in this.headers is most probably pointing to your FileReader when the callback function is run. This because of the nature of JS and it's way of handling with the this keyword.

Solution: above your files variable, declare var self = this and call self.headers. Do this with tickets as well.

I recommend you to watch this video about this from MPJ: https://www.youtube.com/watch?v=GhbhD1HR5vk

Alexb0903's avatar

Hi, Thanks for the quick reply!

I tried the fix you propose and it still doesn't work. I logged my this and it seem to be my vue component. I will have a check your video to learn a little bit about those context.

Btw i noticed something in my log that might be the problem. On my get_row_function i get a notice that says This value as evaluated just now

mabdullahsari's avatar

You initialize your headers value as a string. Perhaps you should initialize it as an array and push your headers directly onto it so Vue's reactivity system can kick in.

Thanks for the heads up, I guess Vue handles the this binding automatically.

Alexb0903's avatar

Thank you very much I found the solution and your awnser helped me. You were right when you said that the this was in fact the FileReader. I just didnt notice at first because there was another problem. The method was receiving async awnser for some reason so I found in the vue Documentation that we need to use this code in order to update

 self.$nextTick();

Please or to participate in this conversation.