Get distinct values under the same key from an array of objects

In my Vue application, I received an API response containing information about various products:

productData = [{
    "id": 4,
    "name": "product02",
    "image": "https://example.com/images/example.png",
    "variations": [{
        "id": 1,
        "price": "10.00",
        "stock": 0,
        "color": "white",
        "sex": "male",
        "size": "42"
    }, {
        "id": 2,
        "price": "10.00",
        "stock": 0,
        "color": "white",
        "sex": "male",
        "size": "39"
    }, {
        "id": 3,
        "price": "10.00",
        "stock": 0,
        "color": "white",
        "sex": "male",
        "size": "39"
    }]
}, {
    "id": 5,
    "name": "product",
    "image": "https://api.pre.runrunsports.com/api/imagees_productos/figura1_8.png",
    "variations": [{
        "id": 33,
        "price": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "male",
        "color": "white"
    }, {
        "id": 34,
        "price": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "male",
        "color": "blue"
    }, {
        "id": 35,
        "price": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "male",
        "color": "black"
    }, {
        "id": 36,
        "price": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "male",
        "color": "red"
    }]
}]

I'm facing an issue with extracting unique values for attributes like size, color, and sex for each product to populate a <select>. Additionally, I need to dynamically retrieve the corresponding price based on user selections of sex, color, and size.

At this stage, I'm stuck with the following simplified code:

new Vue({
  el: '#list-example',
  data: {
    productData: [{
      id: 4,
      name: "product02",
      image: "https://example.com/images/example.png",
      attributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      variations: [{
          id: 1,
          price: "10.00",
          stock: 0,
          color: "white",
          sex: "male",
          size: "42"
        },
        {
          id: 2,
          price: "10.00",
          stock: 0,
          color: "white",
          sex: "male",
          size: "39"
        }, {
          id: 3,
          price: "10.00",
          stock: 0,
          color: "white",
          sex: "male",
          size: "39"
        }
      ]
    }, {
      id: 5,
      name: "product",
      image: "https://example.com/images/example.png",
      attributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      variations: [{
        id: 33,
        price: "10.00",
        stock: 0,
        size: "41",
        sex: "male",
        color: "white"
      }, {
        id: 34,
        price: "10.00",
        stock: 0,
        size: "41",
        sex: "male",
        color: "blue"
      }, {
        id: 35,
        price: "10.00",
        stock: 0,
        size: "41",
        sex: "male",
        color: "black"
      }]
    }],
  },
  methods: {

  }
})
ul {
  list-style: none;
}

span.title {
  font-size: 20px;
  margin-bottom: 20px;
}

.price {
  font-size: 30px;
  color: red;
}

select {
  max-width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="list-example">
  <ul>
    <li v-for="(product, index) in productData" v-bind:key="product.id">
      <span class="title">{{product.name}}</span>
      <div class="form-group valid col-12 field-select" v-for="(attribute, index) in product.attributes" :key="`attribute-${index}`">
        <label v-bind:for="index + product.id"><span>Select {{ attribute }}</span>
                    </label>
        <div class="field-wrap">
          <select v-bind:id="index + product.id" class="form-control">
            <option v-for="variation in product.variations" :key="variation.id">
              {{ variation }}
            </option>
          </select>
        </div>
      </div>

      <span class="price">
      50€ 
    </span>
      <p>(get the price dynamically depending on user selection)</p>
    </li>
  </ul>
</div>

Any assistance on how to tackle this would be greatly appreciated. Thank you for your time!

Answer №1

If you're facing a similar issue, consider implementing Lodash's uniqBy method to retrieve a distinct list of values for each attribute:

    <select v-for="(value, attr) in product.attributes" class="form-control">
        <option v-for="combo in uniqueValuesForAttribute(product.combinations, attr)">
            {{ combo }}
        </option>
    </select>

    ...

    methods: {
        uniqueValuesForAttribute(combos, attribute) {
            return _.uniqBy(combos, attribute).map(item => item[attribute]);
        }
    }

After selecting your desired values, you can determine the price using this approach:

    getPrice(product, selections) {
        const { color, type, size } = selections;
        const combo = product.combinations.find(comb => {
            return comb.color === color && comb.type === type && comb.size === size;
        });
        return combo.price;
    }

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

Apollo Client is not properly sending non-server-side rendered requests in conjunction with Next.js

I'm facing a challenge where only server-side requests are being transmitted by the Apollo Client. As far as I know, there should be a client created during initialization in the _app file for non-SSR requests, and another when an SSR request is requi ...

Upgrading ASP.Net MVC Web Application with the latest Bootstrap version 5

After updating Bootstrap from version 3.4.1 to 5.1.3, I encountered a similar issue as the original poster in this question. Thankfully, I was able to resolve it thanks to the provided answers. Now, when I click on the hamburger icon, the Navbar expands bu ...

Building a Vue.js testing application on a web server

When testing my app locally on my computer, I can easily run npm run serve. But how can I achieve the same functionality on my server? Where should I direct my domain to? Do I always need to run npm run build and direct my domain to /dist whenever I want ...

Is there a way to turn off TypeScript Inference for imported JavaScript Modules? (Or set it to always infer type as any)

As I attempt to utilize a JS module within a TypeScript File, I encounter errors due to the absence of type declarations in the JS module. The root cause lies in a default argument within the imported JS function that TypeScript erroneously interprets as ...

Items seem to vanish into thin air and become immovable when attempting to relocate them

I am attempting to create a unique grid layout with 3x3 dimensions, where each grid item represents a fragment of a single image. These items should have the capability to be dragged and dropped inside another 3x3 grid, in any desired sequence. I have hit ...

How to showcase a list from intricate JSON data using Angular

I recently came across this pre-existing JSON data that I am unable to change: {"tags": [ { "title": "news", "options": [ { "title": "important", }, { "title": "less important", ...

Updates made in MobX store are not displaying in the web browser

Why are the data changes not reflecting in the view after the api call? Here is the code snippet that might help: store.js import axios from 'axios'; import {encrypt, decrypt} from '../utils/pgp.js' import {observable, action, compute ...

JavaScript code for modifying style properties

Is there a way to modify this function so that when the heading is changed successfully, a "Change Back!" button appears? And then, with a click on the button, the heading is reset and the button disappears again. function changer () { var textArea = ...

Slow transition with a gradual appearance and disappearance for the background

I am currently implementing a fading background image effect on my web page, where the current image fades out as the next one fades in. Here is my code: var backgrounds = []; backgrounds[0] = './img/bg.jpg'; backgrounds[1] = '. ...

Initialization of Arrays with Default Values

I have taken on the task of converting a C++ program into JavaScript. In C++, when creating a dynamic array of type float/double, the entries are automatically initialized to 0.0; there is no need for explicit initialization. For example, a 1-D vector of ...

PhantomJS - Error: Variable "$" is not defined

I am encountering an issue with my PhantomJS script. It runs smoothly on my local machine (Mac), but when I try to run it on my Linux server, I receive the following error message: ReferenceError: Can't find variable: $ https://fantasy.premierleague. ...

Presenting the output of a machine learning model on a website

Currently, I am delving into RESTful Flask API and to enhance my learning experience, I decided to create a compact web form using HTML. Below is the snippet of code for the HTML form. <!DOCTYPE html> <html> <h2>User Input</h2> < ...

Strange behavior of shadows within Three.js

I've been working on creating a mini solar system but encountered an interesting issue. I want all the planets to cast and receive shadows from each other, but it seems like the shadow casting depends on the order of instancing. Here is the code for t ...

Issue with loading Squarespace form when executing jQuery on Internet Explorer

One challenge I'm facing is that Squarespace builds their forms using JavaScript (YUI) and loads their code on document ready. How can I ensure that my code waits until their form is fully loaded? This issue seems to only occur in Internet Explorer. ...

To display the elements of an array in a dropdown menu

I have a collection of arrays within an object. {"ItemIsExportControlled":["true","false"],"OrderShippingDestination":["domestic","foreign"],"OrderShipping":["ground","air","sea"],"ItemStockStatus":["validInStock","invalid","validOutOfStock"],"OrderDelive ...

Assign the values from the axios response to variables within the exported const

Currently, I am incorporating axios into my vue.js application to perform an HTTP POST request and retrieve some variables for a vue-echart. However, I have encountered a bit of a roadblock in determining the most effective approach. The snippet below is ...

Possible Inconsistencies with the LookAt Feature in Three.js

Attempting to use the lookAt function to make zombies move towards the character has been a challenge. The problem lies in the fact that they are not turning correctly but at odd angles. Here is the code snippet I tried: var pos = new THREE.Vector3(self ...

Accessing an image from a directory using Javascript

I have a simple question that I need help with. In my code, I currently pull images from a website using this syntax: icon: 'http://i45.tinypic.com/2yua8ns.png'. However, I would like to use something like this instead: icon: '\images/i ...

personalize auto-suggestions in AngularJS

Here is a link to a custom search implementation using autocomplete in angularjs. Is it possible to modify this so that the matching starts from the first character? HTML <div ng-app='MyModule'> <div ng-controller='DefaultCtrl& ...

When a jQuery click event is triggered, the event.target will return the child element that was clicked within the

When I have a jQuery click event assigned to a hyperlink that contains an image, each with separate ids, I expect clicking the hyperlink to trigger the code event.target.id, returning the hyperlink's id. However, it actually returns the image's i ...