Utilize computed properties in Vue to dynamically load a nested JSON array into a select dropdown

Initially, in my Vue component, I had a series of nested if statements to iterate through the JSON data and determine whether to display a text input or a select based on a has_selectable_value option being true (displaying select) or false (displaying text input). However, I have now transitioned to using a computed statement that accomplishes most of what I need, except for displaying the select options.

Below is the relevant part of the Vue Code:

<template v-else-if="searchtype == 9">
    <select v-for="service in selectableServices" class="form-control" v-model="searchvalue" required>
        <option value="">Select A Location</option>
        <option v-for="sl in selectableLocations" :value="sl.location_id">{{sl.name}}</option>
    </select>
    <input v-for="service in nonSelectableServices" class="form-control" v-model="searchvalue" placeholder="Enter Search Value" required>
</template>

The existing computed functions are as follows:

services: function () {   
    var ret = []
    this.countries.forEach(function(country) {
        country.states.forEach(function(state) {
            state.services.forEach(function(service) {
                ret.push(service)
            });
        });
    });

    return ret;               
},
selectableServices: function () {
    return this.services.filter(service => service.id == this.service && service.has_selectable_location);
},
nonSelectableServices: function () {
    return this.services.filter(service => service.id == this.service && !service.has_selectable_location);
},
selectableLocations: function () {
    // Filtering one more level down
    return this.selectableServices.map(service => service.selectablelocations);
},

This is the structure of the JSON data being worked with (relevant parts only):

[
    {
    "id": 1,
    "name": "Country Name",
    "states": [
        {
            "id": 1,
            "name": "State Name",
            "services": [
                    {
                    "id": 1,
                    "name": "Service Name",
                    "has_selectable_location": 1,
                    "selectablelocations": [
                            {
                                "id": 1,
                                "name": "Selectable Location A",
                            },
                        ]
                    }
                ]
            }
        ]
    }
]

By using a Vue plugin for Chrome, it was observed that the computed function selectableLocations loads an array containing the individual locations, but the current v-for statement is unable to function correctly. Therefore, another level needs to be added by incorporating an extra v-for loop like so:

<template v-for="selectableLocationsList in selectableLocations" >
    <option v-for="sl in selectableLocationsList"  :value="sl.location_id">{{sl.name}}</option>
</template>

While everything displays correctly with this approach, there might be better practices available. The aim was to handle most of this within computed functions and ideally utilize just a single v-for statement. If this limitation remains, I am willing to maintain the existing setup.

Thank you for your help.

Edit: Following additional testing and research, the following code was devised to achieve the desired outcome:

var formArray = []
var locationsArray = this.servicesArray.filter(service => service.id == this.service);

locationsArray.map(service => service.selectablelocations);

locationsArray.forEach(function(selectableLocations) {
    selectableLocations.selectablelocations.forEach(function(location) {
        formArray.push(location)
    });
});

return formArray;

Is there a way to further optimize this code for cleaner execution?

Answer №1

After reviewing the code snippet you provided following the Edit, some improvements can be made:

const newArray = [];

newArray = this.itemsArray
  .filter(item => item.id === this.item)
  .map(item => item.options)
  .reduce((previous, current) => previous.concat(current));

return newArray;

It's worth noting that the map function used in your code doesn't perform any modifications as Array.prototype.map simply creates a new array without assigning it to any variable.

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

Nested Ajax request fails and triggers a full page reload

My goal is to search for product information and images using a product code input on index.php. The query runs in open_first.php via an ajax post request, which works perfectly. open_first.php displays images that can be selected by clicking on them. How ...

Exploring virtual properties with Mongoose queries

Recently, I came across a situation where I have a model of a Person with a virtual field called full_name. This virtual field combines the first name, middle names, and last name of an individual. It proves to be very helpful when I need to search for a p ...

VueJS - repeating input fields for file uploads

I need help removing duplicate items from an array in JavaScript, but when I try to delete one, it always deletes the last occurrence! https://i.sstatic.net/NeJRJ.jpg let app = new Vue({ el: '#app', data: { items: [] }, methods: { ...

Uncertain about how to transfer data between server and client in Next.js?

I'm currently grappling with understanding the proper method of exchanging data between server-side and client-side components in NextJS 13. To simplify my learning process, I have created a basic scenario. In this setup, I have two functions that pe ...

Upon successful authorization, the Node Express server will pass the access token to the React client app via OAuth in the callback

I am currently working on a node server that authenticates with a third party using oauth, similar to how Stack Overflow does. After authorizing the request and obtaining the access token and other essential information from the third party, my goal is to ...

The 'fn' argument passed is not a valid function, instead it is a string

I am encountering an issue while trying to retrieve data from my server. The console doesn't provide any specific information about the error. My objective is to fetch JSON data from the server and use it to display the required information. I am util ...

The requested item could not be found: An error was encountered (NoSuchKey) while attempting to retrieve the object: The provided key is not present

Attempting to retrieve a file from s3, but encountering the following error: NoSuchKey: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist. import boto3 s3 = boto3.resource('s3') bucket_name = &q ...

Using include_once() function while encoding JSON in PHP may result in a SyntaxError

REMINDER: XAMPP USAGE While working with PHP, I am utilizing json_encode() to send data back in response to a JS/JQuery ajax request. The ajax call from .js file: $.ajax({url: "/sys/search_rf/functions.php" , async: false, // wait for reponse typ ...

Ensuring that a canvas remains centered and completely visible within its parent element while zooming in React

Currently, I am developing a straightforward PowerPoint creator using React. In this project, I have integrated a zoom feature for a canvas element. The principle is that the canvas should resize based on a scale factor. However, there seems to be an issue ...

Comparing Strings in JavaScript and PHP

Currently, I have set up an Ajax call with a success function that receives a variable from the PHP page like this. Ajax: $.ajax ({ type: "POST", url: "loginrequest.php", data: 'username=' + username + '&password=' + ...

Using a dynamic image URL from JSON to display it in a bitmap

I used the instructions provided here to print Sample Receipts. This is my JSON data: { "response": { "status": "http://www.neodynamic.com/articles/How-to-print-raw-ESC-POS-commands-from-PHP-directly-to-the-client-printer/php-print-esc-po ...

iteration using underscores in JavaScript

I am currently working on creating an object using underscore and backbone. I have an array of objects, each containing a nested object with different sets of data. Within the array, data[0] holds the name of a location while data[2] contains the coordina ...

Using the function computed in Vue template with Laravel to showcase variables

Could someone assist me with the syntax for displaying a variable from the database and rounding it beforehand? <h2 class="txt-bold">Rating: {{roundHalf(ListOrg.rating)}}</h2> computed: { roundHalf: function(num) { return ...

The function is missing from the object, leading to a script error with jQuery

When using different versions of jQuery, I encountered some issues with saving changes in my application. Initially, with jquery-1.4.4.min.js, everything worked except for the save function due to an error I made. However, when switching to jquery-1.7.1.mi ...

Subsequent calls to React's setState with an array are causing duplicate items to be appended twice

While developing a simple Twitter clone using React, I encountered a strange issue when adding a new tweet. Currently, I store a tweets array locally using the useState hook and employ setState to insert the new tweet into the array. Initially, everything ...

From creating a simple jQuery fiddle, let's delve into the world

Here is a code snippet I'm trying to transition from jQuery to an Angular directive. Visit this link to view the original code: http://jsfiddle.net/rhtr1w04/ Below is my implementation in app.js: angular.module('app',[]).directive('an ...

What is the best way to incorporate modules into the client side of TypeScript projects?

I'm currently developing a TypeScript project for client-side JavaScript code. Prior to using TypeScript, I used to import a module in vanilla ES6 JavaScript like this: import * as THREE from 'https://threejs.org/build/three.module.js'; H ...

Troubleshooting the issue with Vue 3 props not being updated

In my parent component, the structure is as follows: <template> <button @click="initStr" value="init str" /> <child :str="str" /> </template> <script> export default { components: { child, } ...

Can a component be added with the press of a button?

Let's tackle this challenge together: I have a button that, when clicked, should add my-component to the DOM. If the button is pressed twice, there should be two <p> tags appended. How can I make this happen? JS: <script> Vue.compone ...

Unveiling the method to fetch the emitted value from a child component and incorporate it into the parent component's return data in Vue

How can I retrieve the title value passed by the Topbar component and incorporate it into the data() return section? I attempted to create a method to pass the value, but was unsuccessful despite being able to successfully log the value in the parent file. ...