skip to Main Content

I’m working with data sent from an api. I need to iterate through this info in order to render html elements. I have a problem with the ‘subjects’ data below as it is sent as a string, but I can only work with this as an array.

Sample json

{
    "employees": [
        {
            "id": 7099,
            "subjects": "English,Biology",
        },
        {
            "id": 7100,
            "subjects": "English,French",
        },
        {
            "id": 7101,
            "subjects": "Maths,Science",
        },
        {
            "id": 7102,
            "subjects": "English,Chemistry",
        },
        {
            "id": 7103,
            "subjects": "English,Biology,Chemistry",
        }
    ]
}

Here is a simplified version of my current component code in vue:

<template>    
  <div  v-for="employee in employees" :key="employee.id">
    <div v-for="subject in employee.subjects" :key="subject"> 
      {{ subject }} 
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      employees: []
    }
  },
  mounted() {
    fetch('http://localhost:3000/employees')
      .then(response => response.json())
      .then(response => this.employees = response)
  }
}
</script> 

I had a similar problem earlier, where I was recommended here to send the ’employee.subjects’ to a function that would split the strings and return them to be inserted into the html. This worked great, but it will not work in this situation as I will need to filter the data by subject before inserting the data into the html.

As far as I understand, I need to loop through the json, collect the ‘subjects’, split them, store this into a new array, and then insert back into the original ‘this.employees’.

About the furthest I’ve managed is below:

this.employees.forEach((employee) => {}

I’m not too sure how to go about this. It seems like a simple enough task, but nothing I try seems to work. Any ideas would be appreciated.

3

Answers


  1. If I understand correctly, response contains the structure you’re showing and you want to transform those strings to arrays when assigning to this.employees? Something like this?:

    .then(response => this.employees = {
      employees: response.employees.map(employee => ({
        ...employee,
        subjects: employee.subjects.split(',')
      }))
    })
    

    For example:

    const response = {
        "employees": [
            {
                "id": 7099,
                "subjects": "English,Biology",
            },
            {
                "id": 7100,
                "subjects": "English,French",
            },
            {
                "id": 7101,
                "subjects": "Maths,Science",
            },
            {
                "id": 7102,
                "subjects": "English,Chemistry",
            },
            {
                "id": 7103,
                "subjects": "English,Biology,Chemistry",
            }
        ]
    };
    
    const employees = {
      employees: response.employees.map(employee => ({
        ...employee,
        subjects: employee.subjects.split(',')
      }))
    };
    
    console.log(employees);
    Login or Signup to reply.
  2. I think you are trying to turn the subjects into a list and template them. If that is the case, you can do something like map the subjects and split them on the "," character. This will turn them into an array. I then run it through a forEach loop using the template to display them as HTML. I would not recommend setting innerHTML in production like I do in the example. But it seems you are using handlebars or something similar.

    I also removed the duplicates by creating a set incase you want to dedup it, but can be removed easily. By removing this:

    Array.from(new Set(<Dont remove this part>))

    const dumbyData = {
        "employees": [
            {
                "id": 7099,
                "subjects": "English,Biology",
            },
            {
                "id": 7100,
                "subjects": "English,French",
            },
            {
                "id": 7101,
                "subjects": "Maths,Science",
            },
            {
                "id": 7102,
                "subjects": "English,Chemistry",
            },
            {
                "id": 7103,
                "subjects": "English,Biology,Chemistry",
            }
        ]
      }
    const template = `<div  v-for="employee in employees" :key="employee.id">
        <div v-for="subject in employee.subjects" :key="subject"> 
          {{ subject }} 
        </div>
      </div>`
      
    function mounted() {
        return fetch('http://localhost:3000/employees')
          .then(response => response.json())
          .catch(()=>{return dumbyData})
    }
    const init = async () => {
      const subjects = await mounted()
      const subjectsAsArray = Array.from(new Set(subjects
        .employees
        .map(({subjects})=>subjects.split(","))
        .flat()
        ));
        
      const newArray = subjectsAsArray
        .map((subject)=>{
        const templatedHtml = template.replace("{{ subject }}",subject)
        document.body.innerHTML += templatedHtml
      })
      
      
      
    }
    init()
    Login or Signup to reply.
  3. the main change you need to do is:

    this.employees = response.employees.map((e) => ({
      ...e,
      subjects: e.subjects.split(","),
    }))
    

    so your code becomes:

    <template>
      <p v-for="employee in employees" :key="employee.id">
        <div v-for="subject in employee.subjects" :key="subject">
          {{ subject }}
        </div>
      </p>
    </template>
    
    <script>
    export default {
      data() {
        return {
          employees: [],
        };
      },
      mounted() {
        fetch("http://localhost:3000/employees")
          .then((response) => response.json()).catch(() => mydata)
          .then(
            (response) =>
              (this.employees = response.employees.map((e) => ({
                ...e,
                subjects: e.subjects.split(","),
              }))),
          );
      },
    };
    
    const mydata = {
      employees: [
        {
          id: 7099,
          subjects: "English,Biology",
        },
        {
          id: 7100,
          subjects: "English,French",
        },
        {
          id: 7101,
          subjects: "Maths,Science",
        },
        {
          id: 7102,
          subjects: "English,Chemistry",
        },
        {
          id: 7103,
          subjects: "English,Biology,Chemistry",
        },
      ],
    };
    </script>
    

    working demo: https://livecodes.io/?x=id/ftgubbhfx5i

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search