Divide a string within a JSON object and output it as an array

I've encountered a challenge while working with data received from an API. My goal is to loop through this information and generate HTML elements based on it. The issue lies in the 'subjects' data, which arrives as a string but needs to be manipulated as an array for my purposes.

Here's a glimpse of the sample JSON structure:

{
    "employees": [
        {
            "id": 7099,
            "subjects": "English,Biology",
        },
        ...
    ]
}

Below is a simplified version of the Vue component code I'm currently working with:

<template>
  ...
</template>

<script>
...
</script>

In a previous scenario, I resolved a similar issue by creating a function to split the strings within 'employee.subjects'. However, this approach won't suffice here since I need to filter the data based on subjects before integrating it into the HTML.

My understanding is that I need to iterate over the JSON, extract the 'subjects', split them, save them into a new array, and then replace the original 'this.employees' with this modified array.

The farthest I've reached so far is shown below:

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

I'm feeling stuck on how to proceed. While the task appears straightforward, none of my attempts seem to yield results. Any suggestions or insights would be greatly appreciated.

Answer №1

the key change needed is:

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

thus, the revised code will be:

<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>

see a live demo here:

Answer №2

If my comprehension is accurate, the variable response contains the structure you've presented and your objective is to convert those strings into arrays when assigning them to this.employees. Is this what you have in mind?

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

Here's a sample scenario:

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);

Answer №3

It appears that you are attempting to convert the subjects into a list and template them. To achieve this, you can map the subjects and split them using the "," character to create an array. Subsequently, you can utilize a forEach loop with the template to exhibit them as HTML. It's worth noting that setting innerHTML in production may not be ideal, unless you are utilizing handlebars or a similar tool.

In addition, I have eliminated duplicates by employing a set to ensure deduplication if needed. The removal process involves:

Array.from(new Set(<Keep this section>))

const sampleData = {
    "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 afterMount() {
    return fetch('http://localhost:3000/employees')
      .then(response => response.json())
      .catch(()=>{return sampleData})
}
const start = async () => {
  const subjects = await afterMount()
  const subjectsAsArray = Array.from(new Set(subjects
    .employees
    .map(({subjects})=>subjects.split(","))
    .flat()
    ));
    
  const updatedArray = subjectsAsArray
    .map((subject)=>{
    const templatedHtml = template.replace("{{ subject }}",subject)
    document.body.innerHTML += templatedHtml
  })
  
  
  
}
start()

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to apply color to a line-through click event in React without affecting the font color?

I'm attempting to change the click event on a line-through element to turn red when clicked, but I can't find any solutions. I've tried various methods with no success. Edit: After adding "color":"red" following "none", the line is now red, ...

Retrieve a specific value from an array of objects by searching for a particular object's value

Here is an example of an array of objects I am working with: $scope.SACCodes = [ {'code':'023', 'description':'Spread FTGs', 'group':'footings'}, {'code':'024', ' ...

Is it possible for numerous identical components to trigger the display of the identical modal on a single webpage?

I am currently utilizing Vue in my project and I have a component that displays a button. When this button is clicked, it triggers a modal to open which is also part of the same component. The functionality works as intended. However, if there are multipl ...

Accessing JSON data model from Ember route or controller

Exploring the capabilities of Ember.js Is it possible to expose my data model as JSON through a route or controller? The object saved in the store looks like this: this.store.createRecord('Person', { id: 1, name: this.get('name'), ...

What causes differences in the resulting width between buttons and inputs as opposed to divs and anchor tags?

Check out this JS Bin: http://jsbin.com/ojiJEKa/1/edit I have a question regarding the different width results of <div> and <a> compared to <input> and <button>, even though they have the same style applied. Can anyone explain why ...

Redis appears to be missing the expected results

After following an express demo which involved storing and retrieving values with Redis, I attempted to implement the code in my own Express app. However, I encountered issues as the req.online variable was returning null when I tried to retrieve its lengt ...

Send both file and model data using AngularJS with FormData

When uploading an image using the file input type along with other user data, my model includes the User class: public class User { public int Id { get; set; } public string Name { get; set; } public int Rollno { get; set; } public byte[] ...

Push the accordion tab upwards towards the top of the browser

I am working on an accordion menu that contains lengthy content. To improve user experience, I want to implement a slide effect when the accordion content is opened. Currently, when the first two menu items are opened, the content of the last item is disp ...

What could be causing the React variable to malfunction within my state object?

class ColoredSquares extends React.Component { constructor() { super(); this.selectedColor = 'green'; } state = { backgroundColor: this.selectedColor, width: "50px", height: "50p ...

Manipulating DOM elements using JavaScript Vanilla with the Jquery <<S.fn.init [selector]>> framework

I have a project where I need to switch the logic written in jQuery to vanilla JavaScript. Here is an overview of my code: I am using the keydown event on an input element to trigger a function that searches an API based on the input value. var selectedU ...

Is it possible to keep my JavaScript scripts running continuously within my HTML code?

I recently set up a JavaScript file that continuously queries an API for updates. It's currently linked to my index.html, but I'm looking for a way to keep it live and running 24/7 without requiring the browser to be open. Any suggestions on how ...

Ways to determine if a website is being accessed from a mobile device or a computer without relying on TeraWurfl technology

After my search on the internet yielded no answers, I decided to post my question here. Is there a method available to detect whether a site is being accessed from a computer or mobile device without using TeraWurfl? I'm looking for a simple code snip ...

Utilize Material-UI slider components to dynamically manage slider handles

I am trying to dynamically create sliders based on user input and struggling with saving values when they are changed. Below is the code snippet I have implemented so far. The issue I'm facing is that I cannot retrieve the value using event.target.val ...

Using a render target causes certain elements of my visual graphics to become hidden

Hey there, I've been experimenting with render targets lately and encountered some issues. I've put together a simplified example below: init = function() { // RENDERER canvas = document.getElementById("mycanvas"); renderer = new THREE ...

Problem with RadioButton click event not triggering

Among my collection of RadioButton elements, there is an onclick event that should trigger. This event, named SecurityCheckedChanged, will display or hide other div containers (populated with RadioButton elements) based on the selected RadioButton. Howeve ...

Using Json.NET to Append JObject to existing JArray

Struggling with a seemingly simple piece of code, can't seem to figure it out. JObject obj = new JObject { "Name", "John" }; JArray array = new JArray(); array.Add(obj); // receiving error message: "Can not add Newtonsoft.Json.Linq.JValue to Newtons ...

How can you execute PHP code within another PHP script without triggering a redirect?

I'm faced with a situation where I have two php files, namely abc.php and def.php. My goal is to only display abc.php in the browser URL bar when it executes. Additionally, upon clicking the submit button on my HTML page, abc.php should be triggered t ...

Having trouble getting Material-UI classes to work with external SVG icons?

I recently crafted a Material-UI persistent drawer that contains a list item component designed to alter the icon color upon user interaction. However, my styling adjustments only seem to apply to Material-UI icons and not external SVG ones. If you'r ...

What is the Vue3 counterpart to the concept of a 'template'?

Vue2 provides the template property which allows rendering HTML from a string: new Vue({ el: "#app", template: "<h1>Title</h1>" }) I leverage this property to load templates from a separate webpack loader that uses the ...

Learn how to implement interconnected dropdown menus on an html webpage using a combination of JavaScript, AngularJs, and JSON dataset

Incorrect HTML code example: <div ng-app="myApp" ng=controller="myCtrl"> States : <select id="source" name="source"> <option>{{state.name}}</option> </select> Districts: <select id="status" name="status"> ...