Search code examples
cssvue.jsvue-componenttext-align

VUEJS: Is it possible to process/modify data retrieved through v-for before displaying?


Hello I am extremely new to web application development / javascript in general. Only gave myself crash courses from udemy videos for the past 4 months.

For my web application, I am retrieving data from a database through my server-side backend with axios. I have a logRepository Array where the retrieved data is pushed.

data() {
      return {
        logRepository: [],
      }
    },
created() {
      axios.get('/myrestapiroute', {
        headers: {
          'Authorization': `Bearer ${this.$store.state.token}`
        },
        params: {
          userId: this.userId
        }
      })
      .then(res => {
        const data = res.data.logs
        this.dataCheck = data
        for(let key in data) {
          const log = data[key]
          log.id = key
          this.logRepository.push(log)
        }
      })

On my template, I used v-for to loop through all the retrieved data elements:

 <div ..... v-for="(log,index) in logRepository" :key="index">

With the v-for in place, one example of how I display my data as such in a paragraph tag. The format is due to how the data was structured.

<p style="text-align: justify;">
 {{ log.logId.jobPerformed }}
</p>

The problem arises when I try to apply styling to the text. As you can see above, I would like to use text-align: justify. I also wanted to keep the whitespace as how it was input by the user through the use of white-space: pre-wrap.

(https://i.sstatic.net/IDSAL.png)

But the problem is these two styles do not work together well. As can be seen below in the picture, if I use justify on its own, it behaves normally (Except that whitespace is lost). However, if I combine both text-align:justify and white-space: pre-wrap, the text end up justified with spacing, but aligned in a weird way.

(https://i.sstatic.net/NvLuc.png)

For short entries, they begin with weird indentation when the starting side should be aligned to the left of the column. The issue appears to be more than simply whitespaces at the start as I have tried .trim() as suggested by a contributor.

(https://i.sstatic.net/NK1n7.png)

I tried to tweak the CSS around, with text-align-last, text-align-start, direction: ltr, pre-tags etc. But it just does not work properly. Suggestions from other SO pages recommended that the data be processed by performing a string replace of all \n to br before displaying.

Is it possible to perform processing for individual data obtained from v-for before displaying or it has to be done to the array using computed property?

Since my data is to be fetched from a database, I am confused on how to achieve the pre-processing of data, since my array size will dynamic and differ for each user.

What would be the most optimal way to achieve pre-processing of data before displaying for such case?

This image below is how my Array of Object (logRepository) looks like. The format is largely due to mongoDB schema. (https://i.sstatic.net/MEUAY.png)

======= Solution =======

I modified the object variables in my .then block and performed string replace for all \n characters to
tags.

https://i.sstatic.net/0nN4E.png

With that my display no longer requires the "white-space: pre-wrap" styling. However, since I was previously using string interpolation to display my data the
tags were treated as plain text.

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

I had to modify the tags to use v-html binding to display the data as htmltext so that
would work. The difference can be seen in the last picture.

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

Thanks for helping me on this since I am very new to javascript.


Solution

  • There are a number of patterns you could use here to pre-process your data.

    • Process your data in the then function you have created
    • Wrap the data in functions within the {{ ... }} blocks in the template
    • Create a component that is used as the element that the v-for loop iterates over which displays a computed value
    • Use a computed value as the source array of the v-for directive in the main template. This is often done using a processing function mapped to the source data, as in log.map( data => data.logId.jobPerformed.trim()