Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

oliverbusk's avatar

Vue - parse JSON string

Hi all

I am trying to parse a JSON string that my Laravel application serves to my Vue view. The JSON string can look like this:

{  
   "1":[  
      {  
         "row":"Some text here on first column."
      },
      {  
         "row":"And more text. Second row."
      },
      {
         "row":"Text!"
      }
    
   ],
   "2":[  
      {  
         "row":"2nd column text."
      },
      {  
         "row":""
      }
   ],
   "3":[  
      {  
         "row":"Even more text. But on the third column."
      }
   ]
}

Things to note here:

  1. The "1", "2", and "3" refers to columns. So in above examples, I have 3 columns.
  2. Each "row" refers to a row within the column.

I am trying to parse the string as a table, like: https://jsfiddle.net/59bz2hqs/1/.

This is what I have now:

<template>
    <div>
      <table>
          <tbody>
              <tr v-for="row in this.content">
                 <td>{{row}}</td>
               </tr>
           </tbody>
      </table>
   <div>
</template>

<script>
    export default {
        data() {
            return {
  
                content: []
            }
        },
        created() {
            Event.$on("document-was-processed", content => {
                this.content = content;          
            });
        }
    }

</script>

Now above simply prints out the actual JSON string. Can anyone help me out on how to actually parse the content?

Thanks!

0 likes
10 replies
Dunsti's avatar

Try this:

this.content = JSON.parse(content);

This will give you an array, which you can then iterate over.

1 like
oliverbusk's avatar

@DUNSTI - This gives me an error:

Unexpected token o in JSON at position 1

Laravel already provides the JSON string.

The problem is not getting the JSON string. I already have that in my view. The problem is parsing it in the table format (like I have tried to do in my JSFiddle manually).

MaverickChan's avatar

you can't do it . you have un-equal width columns , so it will never fit the table.

in every td , you should give it a string (object is fine but it dosen't show the data you want).

in every row loop , it has an one element array , the array contains several objects from 1 to 3.

so , too many layers can't be done with 1 single loop.

oliverbusk's avatar

@MAVERICKCHAN - But can't this be achieved, that if there is no row set, it should just be an empty <td></td>?

EmilMoe's avatar

The more logically setup would be that every node is a row, not a column. From there you could either have named properties or just iterate, but you should have a schema for the table setup that describes the number of columns and maybe their header.

hollyit's avatar

Agree with @emilmoe - change your data structure. It should be an array of rows, which contains an array of columns. If you can do that in Laravel, it will be a lot easier in Vue. If not, then I would create a computed property to generate the proper array structure for the table. Then it's a simple case of:

<tr v-for="(row,rid) in rows" :key="rid">
   <td v-for="(col,cid) in row" :key="cid" v-text="col"></td>
</tr>
oliverbusk's avatar

@EMILMOE - @hollyit can either one of you show how the JSON string would then look like? I am a bit puzzled, because in my head, having the columns and then the rows makes sense (that's how you would normally build a table)

oliverbusk's avatar

OK so I played around a bit more.. This is what I came up with:

{
   "1":[
      {
         "text":"Some text here on first column."
      },
      {
         "text":"2nd column text."
      },
      {
         "text":"Even more text. But on the third column"
      }
   ],
   "2":[
      {
         "text":"And more text. Second row."
      },
      {
         "text":""
      },
      {
         "text":""
      }
   ],
   "3":[
      {
         "text":"Text!"
      },
      {
         "text":""
      },
      {
         "text":""
      }
   ]
}

And the vude code:

<table class="text-left w-full border-collapse m-3">
  <thead>
    <tr class="bg-gray-100">

      <th v-for="(item, idx) in this.content" class="p-1">
        {{idx}}
      </th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(row, rid) in this.content">
      <td v-for="(col, cid) in row">{{ col.text }} </td>
    </tr>
  </tbody>
</table>

Now above code seems to work - it generates the desired output (like in my jsFiddle). However, I have a few questions:

  1. Is this the correct way of saving a "table-like" layout in a JSON string?
  2. In above code, I have an equal number of rows in all my columns (3 rows in all columns). This may not always be the case. For example, column 1 can have 10 rows and column 2 can have 15 rows. In this case, how can I ensure that the visual layout "expands" to 15 rows? Should this be made on the backend (PHP: So I simply add empty "text":"" values to the string) - or should it be made on the frontend?
hollyit's avatar

@OLIVERBUSK - My suggestion would be to look at how other Vue table/datatable components work. Bootstrap-Vue is a very common one. If you look in the data() on this page, you'll see the items data that is structured in a row->column structure.

The easiest way to think of it is to vision how the HTML needs to look in the end and model your data similar to that. Tables have rows. Rows have children. So you need to walk down the nesting levels to get to each item. The table is your overall data structure. Inside that table you have multiple rows (), which is your next level down. Inside each row you have multiple columns (), which is the next level.

Please or to participate in this conversation.