Exploring the usage of promises with data in VueJS async components

Experimenting with VueJS 2.0 RC and utilizing the fetch API to retrieve data for certain components. Here's a sample scenario:

const Component = {
  template: '#comp',
  name: "some-component",
  data: function () {
    return {
      basic: data.subset,
      records: function () {
        return fetch('/datasource/api', {
          method: 'get'
        }).then(function (response) {
          return response.json();
        }).then(function (response) {
          if (response.status == "success") {
            return response.payload;
          } else {
            console.error(response.message);
          }
        }).catch(function (err) {
          console.error(err);
        });
      }
    }
  }
};

The data object represents a global application state, defined prior to the app's initialization. Only a portion of it is necessary in the component, hence the subset. The primary set of data for the component originates from another endpoint that I'm attempting to access. However, the data property requires an object, yet it's receiving a Promise that can't be effectively utilized within a loop in the template for rendering, such as v-for="record in records".

Am I approaching this incorrectly? How can I ensure the records property updates once it's completely fetched? Is there a way to make the code wait until the promise resolves (essentially making it synchronous)? The component is essentially nonfunctional without data, so there will always be a period of waiting before it can be utilized.

What is the most appropriate method to asynchronously populate a component's data field without relying on plugins like vue-async or vue-resource?

(While I could use XHR/jQuery methods for non-promise ajax calls, I am interested in learning how to achieve this using fetch)


Update: I attempted implementing a created hook and a method to load the data, similar to this but encountered issues - in my experiments, the records property fails to update once it's loaded. Despite successfully retrieving the data (as confirmed by console logs).

This might be related to my usage of vue-router and the component being triggered when a link is clicked, rather than being a standard Vue component. Further investigation is required...


Update #2: Continuing to explore the jsfiddle approach above and logging this.records and response.payload to the console, it shows the records object being populated. However, this does not seem to trigger a change in the template or the component itself - Vue dev tools inspection reveals that the records property remains an empty array. Even if I add a method logstuff and a button in the template to call it, and the method logs this.records in the console, it still logs an observer with an empty array:

https://i.sstatic.net/XB0kC.png

Now, I am questioning why the data property of a component is not updated even after being explicitly set to a different value. I attempted setting up a watcher for $route triggering the reload method, but with no success - every subsequent load of that route does trigger a re-fetch, and console logs show this.records as populated (from within fetch), but the actual this.records property remains an empty array.

Answer №1

The solution I found was using the jsfiddle method, but with a slight twist. Here's the specific part that needed adjustment:

reload: function () {
      fetch('/data/api', {
        method: 'get'
      }).then(function (response) {
        return response.json();
      }).then(function (response) {
        if (response.status == "success") {
          this.records = response.payload;
        } else {
          console.error(response.message);
        }
      }).catch(function (err) {
        console.error(err);
      });
    }

It required adding a .bind(this) to ensure the correct execution context when setting the this.records value after fetching data:

reload: function () {
      fetch('/data/api', {
        method: 'get'
      }).then(function (response) {
        return response.json();
      }).then(function (response) {
        if (response.status == "success") {
          this.records = response.payload;
        } else {
          console.error(response.message);
        }
      }.bind(this)).catch(function (err) {
        console.error(err);
      });
    }

For more insights on this topic, I found this post particularly helpful.

This experience taught me the importance of being mindful of scope in modern JavaScript programming.

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

Seems like ngAfterViewInit isn't functioning properly, could it be an error on my end

After implementing my ngAfterViewInit function, I noticed that it is not behaving as expected. I have a hunch that something important may be missing in my code. ngOnInit() { this.dataService.getUsers().subscribe((users) => {this.users = users) ; ...

Encountering "loose option" warnings in the latest installation of Nuxt 2.14.6 with Babel

Recently, I have set up a fresh installation of nuxt version 2.14.6 and I'm encountering an error when running the nuxt command that I would like to resolve: WARN Though the "loose" option was set to "false" in your @babel/preset ...

Utilize querySelectorAll to inspect class properties

When exporting a table to CSV, I have implemented the following logic: var cols = rows[i].querySelectorAll("td, th"); While this method works well, users are able to hide/display columns as they desire. Since AngularJS is used, the hidden columns are mar ...

Creating a custom Higher Order Component to seamlessly connect react-relay and react-router using TypeScript

Hey there! So, my Frankenstein monster project has decided to go rogue and I'm running out of hair to pull out. Any help would be greatly appreciated. I've been working on setting up a simple app with React, React-Router, React-Relay, and Typesc ...

Having trouble establishing a default route with React Router v5

I am facing an issue with setting the default route to the home page in react router v5. Despite trying several methods, I cannot get it to work as expected. Index.js import React from "react"; import ReactDOM from "react-dom"; import ...

Place the div's scrollbar at the beginning of its content

Recently, I put together a custom CSS modal that includes a scrollable div (without the modal itself being scrollable). Interestingly enough, when I initially open the modal, the scrollbar of the div starts at the top as anticipated. However, if I scroll d ...

The NextJS development server is frequently losing connection

Issue While working on my NextJS project, I've been experiencing occasional disruptions with my development server. Whenever I update my code, I encounter random occurrences of the dev server disconnecting and displaying the error message below: Type ...

Events triggered when the mouse hovers over an element and then moves

After spending hours reading articles and watching YouTube videos, I am completely lost. No matter what code I try, it seems like I can never get it right. It's frustrating how such a simple task can be so confusing. I just can't seem to wrap my ...

Eliminate duplicate entries in typeahead.js by ensuring unique data sources for both prefetch and remote

Currently, I have implemented typeahead.js with both prefetch and remote data sources. You can check out the example here. $(document).ready(function() { var castDirectors = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('val ...

Tips for keeping notification icons in the upper right corner of the box?

I am facing an issue with absolute positioning where the notification icons I've positioned to the top-right corner of a box are moving away when the screen size changes. Desired appearance of the image Actual appearance when screen size is adjusted ...

Retrieve the HTML contents of a cell that contains a checkbox with the value of "jquery"

Here is an example of a table row: <tr> <td><input type='checkbox' name='post[]' value="1"></td> <td>08-Apr-2014</td> <td>injj team</td> <td>merchant.testyy.com</ ...

JavaScript - Issue with For Loop when Finding Symmetric Difference

Here is my solution to a coding challenge on FreeCodeCamp called "Symmetric Difference." I'm puzzled as to why my code is returning 2, 3, 4, 6 instead of the expected 2, 3, 4, 6, 7. function sym(args) { args = Array.from(arguments); var new ...

Utilizing production and development configuration files in Angular and JavaScript with Webpack

I'm currently working with Webpack and Angular, trying to find a way to inject/use variables based on whether it's in development or production mode. Although I have Webpack set up to detect the environment (prod or dev), I am facing an issue wi ...

Implementing a watcher property in JavaScript to dynamically add a class to an element

I'm currently facing an issue where I need to apply a class to an element when a certain data property changes. My approach involves using a watcher to monitor the value change and adding a class through JavaScript, as demonstrated in the code snippet ...

I am facing an issue where the module pattern functions perfectly on JSBin, but fails to work properly

As a backend developer, I typically only write JavaScript when absolutely necessary, and not always in the best way. However, I have decided to turn over a new leaf and start writing more organized code that follows best practices as much as possible. To ...

Is it necessary to utilize Babel with Node.js?

I am aware that Node.js fully supports ES6 now, using version 7.2.1. Recently, I was advised by someone that the current ES6 implementation in Node.js may not be production ready and that I might need to use Babel for a more robust ES6 set-up. After visit ...

The Bootstrap validation does not display the appropriate checkmarks

I am using Bootstrap validation and I do not want the green checkmark to be displayed when the inputs are correct. I searched the Bootstrap documentation but could not find a way to hide the green checkmarks. <script> // Here is an example of Java ...

Locked first row and first column in HTML table

I'm struggling with freezing the first row and column in an HTML file exported from Microsoft Excel. When attempting to add position:fixed; to achieve this, I noticed that it changes the size and alignment of the headers. Can someone please advise me ...

Obtaining the data stored in objects within a parse database

I'm currently facing an issue where I am trying to retrieve the name of the creator from the session object, which is a pointer. For testing purposes, I have been attempting to access this information but it keeps showing up as undefined. Any suggesti ...

The hamburger menu functions properly on the homepage but is not working on the individual about page

The burger menu was causing issues initially due to a simple spelling mistake, which I only noticed later. However, the current issue seems more complex. I am now creating separate pages for different sections of my website, such as About Me, Education, et ...