Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set object in data from a method in VUE.js

I have been stuck with this issues for 2 hours now and I really can't seem to get it work.

const app = new Vue({
  el: '#book-search',
  data: {
    searchInput: 'a',
    books: {},
  },
  methods: {
    foo: function () {
      axios.get('https://www.googleapis.com/books/v1/volumes', {
        params: {
          q: this.searchInput
        }
      })
      .then(function (response) {
        var items = response.data.items
        for (i = 0; i < items.length; i++) {

          var item = items[i].volumeInfo;

          Vue.set(this.books[i], 'title', item.title);   

        }
      })
      .catch(function (error) {
        console.log(error);
      });

    }
  }
});

When I initiate search and the API call I want the values to be passed to data so the final structure looks similar to the one below.

data: {
  searchInput: '',
  books: {
    "0": {
       title: "Book 1"
     },
    "1": {
       title: "Book 2"
     }
},

Currently I get Cannot read property '0' of undefined.

like image 521
Svedr Avatar asked Jul 02 '17 09:07

Svedr


People also ask

What does $Set do in Vue?

js $set() method to set data object properties. Binding a class on an item and controlling it by the truthy value of a data property is a powerful feature of Vue.

What does data () do in Vue?

data # A function that returns the initial reactive state for the component instance. The function is expected to return a plain JavaScript object, which will be made reactive by Vue.

What is object assign in VueJS?

Object.assign() The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

How do you assign a value to a prop in Vue?

To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.


1 Answers

Problem lies here:

Vue.set(this.books[i], 'title', item.title);

You are inside the callback context and the value of this is not the Vue object as you might expect it to be. One way to solve this is to save the value of this beforehand and use it in the callback function.

Also instead of using Vue.set(), try updating the books object directly.

const app = new Vue({
  el: '#book-search',
  data: {
    searchInput: 'a',
    books: {},
  },
  methods: {
    foo: function () {
      var self = this;
      //--^^^^^^^^^^^^ Save this
      axios.get('https://www.googleapis.com/books/v1/volumes', {
        params: {
          q: self.searchInput
          //-^^^^--- use self instead of this
        }
      })
      .then(function (response) {
        var items = response.data.items
        var books = {};
        for (i = 0; i < items.length; i++) {

          var item = items[i].volumeInfo;
          books[i] = { 'title' : item.title };
        }
        self.books = books;
      })
      .catch(function (error) {
        console.log(error);
      });

    }
  }
});

Or if you want to use Vue.set() then use this:

Vue.set(self.books, i, {
     'title': item.title
});

Hope this helps.

like image 69
abhishekkannojia Avatar answered Sep 18 '22 16:09

abhishekkannojia