Error: Uncaught (in promise) TypeError: Cannot create property ... on string

9.7k views Asked by At

I'm trying to retrieve data (an array with objects) from my node js server through an ajax request and populate it into my vue instance.

At the following line I get an error:

this.$set('tables', tables);

Error message:

vue.common.js:834Uncaught (in promise) TypeError: Cannot create property '[{"name":"Test","description":"test","id":"58564cd5fdd4e76a09b1f848"},{"name":"Test","description":"test","id":"58564d04902af88009e020e8"},{"name":"test2","description":"teesten","id":"58564d68902af88009e020e9"}]' on string 'tables'

Full code:

<template>
  <div class="container">
    <div class="row">
      <div class="col-xs-12">
        <div class="page-header">
          <h1>Database management</h1>
        </div>
        <h2>Add table</h2>
        <p class="lead">Here you can add a table.</p>
        <form method="post">
          <div class="row">
            <div class="col-xs-12">
              <div class="form-group">
                <label>Table name</label>
                <input v-model="table.name" placeholder="Table name" type="text" class="form-control">
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-xs-12">
              <div class="form-group">
                <label>Table description</label>
                <textarea v-model="table.description" placeholder="Table description" class="form-control"></textarea>
              </div>
            </div>
          </div>
          <button @click.prevent="submit" type="submit" class="btn btn-default">Add table</button>
        </form>
      </div>
    </div>

    <div class="row" v-if="tables.length > 0">
      <div class="col-xs-12">
        <h2>Interact with tables</h2>
        <p class="lead">Here you can interact with your tables.</p>
        <table class="table">
          <thead>
          <tr>
            <th>Table</th>
            <th>Interact</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="table in tables">
            <td>
              {{ table.name }}
            </td>
            <td>
              <button type="button" class="btn btn-default">Enter</button>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
  let table = {
    name: '',
    description: ''
  };

  module.exports = {
    data: function () {
      return {
        tables: [],
        table: table
      }
    },

    created: function () {
      this.getTables();
    },

    methods: {
      submit: function () {
        this.$http.post('/api/user/table', table, {
          emulateJSON: true
        }).then((response) => {
        });
      },

      getTables: function () {
        this.$http.get('/api/user/tables').then((response) => {
            console.log(JSON.stringify(response.body));
          let tables = JSON.stringify(response.body);
          this.$set('tables', tables);
        });
      }
    }

  }
</script>
2

There are 2 answers

0
Tyrone Wilson On BEST ANSWER

From the documentation here it looks like $set() expects 3 arguments and you are supplying 2 where it thinks that 'tables' the string is an object on which you want to set a property and value.

https://v2.vuejs.org/v2/api/#vm-set

The error thinks that you are trying to set a very long property name on a string.

rather do vue.$set(this,'tables', tables)

then you will be setting an attribute called tables on the current object to the array tables.

0
Muthu17 On

The above answer also will work fine.

Try to asign your value directly to you variable and check.

Example :

this.tables = tables

Sample Code

data() : {
   return {
          participants: []
   };
},
...........
methods: {
this.$http.get('/list/participants').then((response) => {
                      console.log(response.body);
                      this.participants = response.body;
                  }, (response) => {
                      console.log('Something wrong');
                  });
 }