No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    How to use data from apollo-client as data-source of QTable?

    Help
    3
    9
    772
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • SB
      SB last edited by

      After switching from static data to the result of an apollo-client query I got the following error:

      TypeError: "can't define property "__index": Object is not extensible"
          rows QTable.js:101
          computedData QTable.js:100
          VueJS 3
          computedRowsNumber QTable.js:140
          VueJS 3
          pagesNumber table-pagination.js:52
          VueJS 9
      
      TypeError: "can't define property "__index": Object is not extensible"
          rows QTable.js:101
          computedData QTable.js:100
          VueJS 3
          computedRows QTable.js:136
          VueJS 3
          getTableBody table-body.js:30
          getBody QTable.js:207
          render QTable.js:179
          VueJS 7
      

      Working with a simple table and iterating over the result array works fine.

      SB 1 Reply Last reply Reply Quote 0
      • SB
        SB @SB last edited by

        Found a solution:

        • use a different variable for QTable data
        • implement a “watch” on the result variable of apollo-client
        • reset QTable data variable with an empty array
        • iterate with forEach over the result variable of apollo-client in the watch function and push each item inside “value” to it’s counterpart in the QTable data variable
        watch: {
          books () {
            this.tableData = []
            this.books.forEach((value) => {
              this.tableData.push({ id: value.id, author: value.author, title: value.title })
            })
          }
        }
        

        Is there a better solution?

        1 Reply Last reply Reply Quote 1
        • s.molinari
          s.molinari last edited by

          How are you calling your data? Can you show the whole code of your component?

          Scott

          SB 1 Reply Last reply Reply Quote 0
          • SB
            SB @s.molinari last edited by

            @s-molinari: Hi Scott, thank you for your quick reply.
            Here ist the code of my component:

            <template>
              <div>
                <q-table
                    :columns="columns"
                    :data="tableData"
                    row-key="id"
                    selection="single"
                    binary-state-sort
                    dense
                />
              </div>
            </template>
            
            <script>
            import gql from 'graphql-tag'
            
            const BOOKS = gql`
              query {
                books {
                  nodeId
                  id
                  title
                  author
                }
              }
            `
            
            const BOOKS_SUBSCRIPTION = gql`
              subscription {
                listen (topic: "books") {
                  relatedNode {
                    ... on Book {
                      nodeId
                      id
                      title
                      author
                    }
                  }
                }
              }
            `
            
            export default {
              name: 'BooksSubscribeToMore',
              apollo: {
                books: {
                  query: BOOKS,
                  subscribeToMore: {
                    document: BOOKS_SUBSCRIPTION,
                    updateQuery: (previousResult, { subscriptionData }) => {
                      if (previousResult.books.find(book => book.id === subscriptionData.data.listen.relatedNode.id)) {
                        return previousResult
                      }
            
                      return {
                        books: [...previousResult.books, subscriptionData.data.listen.relatedNode]
                      }
                    }
                  }
                }
              },
              watch: {
                books () {
                  this.tableData = []
                  this.books.forEach((value) => {
                    this.tableData.push({ id: value.id, author: value.author, title: value.title })
                  })
                }
              },
              data () {
                return {
                  columns: [
                    { name: 'id', label: 'ID', field: 'id', sortable: true, required: true },
                    { title: 'title', label: 'Title', field: 'title', align: 'left', sortable: true },
                    { name: 'author', label: 'Author', field: 'author', align: 'left', sortable: true }
                  ],
                  books: [],
                  tableData: []
                }
              }
            }
            </script>
            
            1 Reply Last reply Reply Quote 0
            • s.molinari
              s.molinari last edited by

              Try just using books as your data (table data) directly.

              Scott

              1 Reply Last reply Reply Quote 0
              • SB
                SB last edited by

                This was my first approach resulting in the errors above.
                After this I take a look at the structure of data (table data) and books.

                SB 1 Reply Last reply Reply Quote 0
                • SB
                  SB @SB last edited by SB

                  Here ist the original code:

                  <template>
                    <div>
                      <q-table
                          :columns="columns"
                          :data="books"
                          row-key="id"
                          selection="single"
                          binary-state-sort
                          dense
                      />
                    </div>
                  </template>
                  
                  <script>
                  import gql from 'graphql-tag'
                  
                  const BOOKS = gql`
                    query {
                      books {
                        nodeId
                        id
                        title
                        author
                      }
                    }
                  `
                  
                  const BOOKS_SUBSCRIPTION = gql`
                    subscription {
                      listen (topic: "books") {
                        relatedNode {
                          ... on Book {
                            nodeId
                            id
                            title
                            author
                          }
                        }
                      }
                    }
                  `
                  
                  export default {
                    name: 'BooksSubscribeToMore',
                    apollo: {
                      books: {
                        query: BOOKS,
                        subscribeToMore: {
                          document: BOOKS_SUBSCRIPTION,
                          updateQuery: (previousResult, { subscriptionData }) => {
                            if (previousResult.books.find(book => book.id === subscriptionData.data.listen.relatedNode.id)) {
                              return previousResult
                            }
                  
                            return {
                              books: [...previousResult.books, subscriptionData.data.listen.relatedNode]
                            }
                          }
                        }
                      }
                    },
                    data () {
                      return {
                        columns: [
                          { name: 'id', label: 'ID', field: 'id', sortable: true, required: true },
                          { title: 'title', label: 'Title', field: 'title', align: 'left', sortable: true },
                          { name: 'author', label: 'Author', field: 'author', align: 'left', sortable: true }
                        ],
                        books: []
                      }
                    }
                  }
                  </script>
                  

                  The code with the watcher works fine but it doesn’t feel “smooth”.

                  1 Reply Last reply Reply Quote 0
                  • SB
                    SB last edited by

                    If you inspect data (table data) after “linking” with QTable you’ll find some aditional things like getters, setters, etc. inside. To protect these additional things QTable seems to use Object.preventExtensions().

                    metalsadman 1 Reply Last reply Reply Quote 0
                    • metalsadman
                      metalsadman @SB last edited by

                      @SB my hguess is you’ll have to deepcopy the table data and thats the one you use for your apollo, re assigned that copy to the model that you gave to your q-table when it changes maybe with a watcher or computed props.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post