What is the proper way to assign an array of objects to an empty array within a Vue component?

I'm currently working on my first Laravel project using Vue components. My setup includes Laravel 8.x and Vue 2.x running on Windows 10. I came across a helpful video tutorial that I'm trying to follow, but some aspects aren't quite working as expected. Yesterday, the community here assisted me in resolving one issue, but now I've encountered a new challenge.

The video demonstrates making a get request with Axios to retrieve data from a MySQL table within the Vue component. The response from Axios contains the data, which is then assigned to an initially empty array in the component's data() section. The empty array definition looks like this:

todos: '',

The method responsible for executing the Axios get request appears as follows:

getToDos() {
        debugger;
        axios.get('/todo')
        .then(function (res) {
            if (res.data.length == 0) console.log("Table is empty");
            else {
                this.todos = res.data
            }
            })
        .catch(function (error) {
            console.log(error);
            })
    },

In the code snippet above, all of the res.data (an array of objects) is simply assigned to the todos array within the data() section. This logic works seamlessly in the video example, where Laravel 7.x is used, whereas in my case with Laravel 8.x, I encounter an error in the Chrome Debugger:

TypeError: this is undefined

This error points to the line where the assignment occurs (this.todos = res.data). While still getting accustomed to JavaScript, it seems odd to assign an array of objects to a variable initialized as an empty string. Despite my expectations, this mismatch doesn't cause any issues for him - could this be related to the Laravel version difference?

After some research and experimentation, including defining todos as an empty array or initializing it differently, I'm consistently facing the same error whenever attempting to assign something to the todos variable. Even methods such as looping through res.data and pushing each object into todos have been unsuccessful. Any insights on why his approach succeeds while mine fails would be greatly appreciated. My goal is to access res.data in the template for displaying relevant information.

Edit: Provided below is the entirety of the component.

    <template>
    <div class="container">
        <form @submit.prevent="addTask"> 
            <div class="input-group mb-3 w-100">
                <input type="text" v-model="form.todo" class="form-control" placeholder="Enter new task" aria-label="Enter new task" aria-describedby="button-addon2">
                <div class="input-group-append">
                    <button class="btn btn-success" type="submit" id="button-addon2">Add new task</button>
                </div>
            </div>
        </form>
        <div class="w-25">
            <h1 class="text-white">...</h1>
            <div v-for="todo in todos" :key="todo.id" class="w-100 text-white">
                {{ todo.title }}
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                todos: '',

                form: new Form({
                    title: '',
                })

            } 
        },
        methods: {
            getToDos() {
                debugger;
                axios.get('/todo')
                .then(function (res) {
                    if (res.data.length == 0) console.log("Table is empty");
                    else {
                        this.todos = res.data
                        // var id = 0;
                        // var title = '';
                        // var completed = false;
                        // for (var ix=0; ix<res.data.length; ix++) {
                        //     id = res.data[ix].id;
                        //     title = res.data[ix].title;
                        //     completed = res.data[ix].completed;
                            // var oneToDo = new Object(res.data[ix]);
                            // this.todos.push(oneToDo);
                        // }   
                    }
                    })
                .catch(function (error) {
                    console.log(error);
                    })
            },
            addTask() {
                let data = new FormData();
                data.append('todo', this.form.todo);
                axios.post('/todo', data)
                .then(function (response) {
                    console.log(response);
                    this.form.reset;
                    this.getToDos();
                    })
                .catch(function (error) {
                    console.log(error);
                    })
            }
        },
        mounted() {
            console.log('ToDoComponent mounted.');
            this.getToDos();
        }
    }
</script>

<style lang="scss" scoped>
.container {
    padding-top: 5em;
}
</style>

Answer №1

When you define a function and use this, the closure of this refers to the function itself. To access the this of the object where the function is defined, arrow functions are needed as shown below:

var obj = {
    getToDos() {
       // 'this' here refers to obj
       axios.get('/todo')
        .then( res =>  {
           this.todos =  res.data
       })
    }

}

For more information on closures in JavaScript, check out these links: https://www.w3schools.com/js/js_function_closures.asp https://medium.com/@vmarchesin/javascript-arrow-functions-and-closures-4e53aa30b774

Answer №2

Implement arrow function by following this pattern for the .then segment

.then((result) => {
    //remaining code goes here
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

UI-Router: What is the best way to access a page within my project without adding it as a State?

Currently in the process of learning Angular and UI-Router. Initially, I followed the advice of many and chose to utilize UI-Router. In my original setup, the login page was included in all States. However, I decided it would be best to keep it as a separ ...

Declining the request to incorporate an external website into my web platform

While checking the console errors in Google Chrome, I encountered the following error message: The page 'https://website.com' was blocked from framing because a higher-level ancestor violates the Content Security Policy directive: "frame-an ...

Using JavaScript to locate and emphasize specific words within a text, whether they are scattered or adjacent

I need help finding a JavaScript code for searching words in a text using a form and a search button. I found one that works for multiple words in a row, but it doesn't work if the words are mixed up. What changes should be made to fix this issue? An ...

Decide on the javascript/jquery libraries you want to include

My app is experiencing slow loading times on the home screen and students using it from school district computers are running into ERR_CONNECTION_RESET errors due to strict firewalls. The excessive loading of javascript and jquery libraries in the head of ...

In Javascript, ensuring a stopping condition for a recursive function that is looping through JSON data

I am having trouble figuring out how to set the break condition for this recursive function. Currently, the function is causing the browser to freeze (seems to be stuck in an endless loop). My goal is to create a series of nested unordered lists based on ...

tips for converting objects into arrays with JavaScript

I have an object and I would like to convert it into an array const object1 = { a: { hide:true}, b:{} }; I am currently using Object.entries to perform the conversion, however, I am struggling with understanding how it should be done. Object.entries ...

Using Webpack postcss prefixer with Vue CLI 3

As I work on implementing Bulma CSS in my project using Vue CLI 3, I encounter the need to prefix the classes with webpack. While I found an example of this process, adapting it from a webpack config to vue.config.js poses some challenges. Here is the ini ...

Guide on transferring information from .ejs file to .js file?

When sending data to a .ejs file using the res.render() method, how can we pass the same data to a .js file if that .ejs file includes a .js file in a script tag? // Server file snippet app.get('/student/data_structures/mock_test_1', (req, res) = ...

When using getStaticPaths, an error is thrown stating "TypeError: segment.replace is not a function."

I am a beginner when it comes to using Next.js's getStaticPaths and I recently encountered an error that has left me feeling lost. Below is the code I have written (using query from serverless-mysql): export async function getStaticPaths() { cons ...

execute action once element has finished loading - angular

I am looking for a way to trigger an angular function after a specific element has been displayed on the page. The challenge arises because this element is part of a Single Page Application (SPA) where its display is controlled by a series of events. Tradi ...

Validate fields by iterating through an object and considering three data points for each field

The struggle is real when it comes to coming up with a title for this question. Suggestions are welcomed! When it comes to field validation, I require three data elements per field: variable name, element ID, and whether it is required or not. Although I ...

What is the best way to retrieve the number of clients in a room using socket.io?

I am using socket.io version 1.3.5 My objective is to retrieve the number of clients in a specific room. This is the code implementation I have: socket.on('create or join', function (numClients, room) { socket.join(room); }); ...

Retrieving data from a dynamic form using jQuery

Can someone assist me with the following issue: I have a dynamic module (generated by a PHP application) that includes input fields like this: <input type="text" class="attr" name="Input_0"/> <input type="text" class="attr" name="Input_1"/> ...

Uncovering the source of glitchy Angular Animations - could it be caused by CSS, code, or ng-directives? Plus, a bonus XKCD comic for some light-hearted humor

Just finished creating an XKCD app for a MEAN stack class I'm enrolled in, and I'm almost done with it. However, there's this annoying visual bug that's bothering me, especially with the angular animations. Here is the link to my deploy ...

Personalized FullCalendar header title

Is there a way to display a unique header title for each calendar in my collection of 16? I've been trying various modifications to the code snippet below with no success: firstDay: <?php echo $iFirstDay; ?>, header: { left: 'prev,next ...

Set the text field to be editable or readonly based on certain conditions

Is there a way to conditionally enable or disable an editable field (edit/read only)? I have tried using session role from the database to set conditions on the text field, but I am unsure of how to proceed... <?php include('session.php'); ?& ...

Utilizing PHP to create an interactive website

As a novice PHP developer, I took to Google in search of tutorials on creating dynamic PHP websites. What I found was that many tutorials used the $_GET variable to manipulate URLs and make them appear like this: example.com/?page=home example.com/?page= ...

Tips for including assisting text in the date field with Material UI

Behold, my component definition: <DateField name={formElement.name} type="date" label={formElement.name} onChange={(date) => formik.setFieldValue(formElement.name, date)} value={formik.values[formElement.name] ...

Switch background color multiple times on click using JavaScript loop

Hello amazing people! I have a container with 52 small boxes and one large box containing a letter. The smaller boxes are arranged around the larger one using CSS grid, and when hovered over, they turn light grey. My Objective When any of the 52 small b ...

Angular Navigation alters the view

I want to navigate to a different page using Angular routing, but for some reason it's not working. Instead of moving to the designated Payment Component page, the content is staying on my Main Component. Why is this happening? app.routing.module.ts ...