0

I got this API response of some products in a Vue app:

products = [{
    "id": 4,
    "name": "producto02",
    "image": "https://example.com/images/example.png",
    "combinactions": [{
        "id": 1,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "42"
    }, {
        "id": 2,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "39"
    }, {
        "id": 3,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "39"
    }, ]
}, {
    "id": 5,
    "name": "producto",
    "image": "https://api.pre.runrunsports.com/api/imagees_productos/figura1_8.png",
    "combinactions": [{
        "id": 33,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "blanco"
    }, {
        "id": 34,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "azul"
    }, {
        "id": 35,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "negro"
    }, {
        "id": 36,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "rojo"
    }]
}]

I'm having a problem with selecting non-repeated values with the same key. I mean, I want to extract for each product and each attribute product the different values of size, color and sex due to put them in a <select>. Then, I will need to get the matched "price" dynamically depending on the user selection by sex, color and size.

I'm stuck at this point right now (reduced code):

new Vue({
  el: '#list-example',
  data: {
    products: [{
      id: 4,
      name: "producto02",
      image: "https://example.com/images/example.png",
      atributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      combinations: [{
          id: 1,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "42"
        },
        {
          id: 2,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "39"
        }, {
          id: 3,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "39"
        }
      ]
    }, {
      id: 5,
      name: "producto",
      image: "https://example.com/images/example.png",
      atributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      combinations: [{
        id: 33,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "blanco"
      }, {
        id: 34,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "azul"
      }, {
        id: 35,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "negro"
      }]
    }],
  },
  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 products" v-bind:key="product.id">
      <span class="title">{{product.name}}</span>
      <div class="form-group valid col-12 field-select" v-for="(atribute, index) in product.atributes" :key="`atribute-${index}`">
        <label v-bind:for="index + product.id"><span>Select {{ atribute }}</span>
                    </label>
        <div class="field-wrap">
          <select v-bind:id="index + product.id" class="form-control">
            <option v-for="combination in product.combinations" :key="combination.id">
              {{ combination }}
            </option>
          </select>
        </div>
      </div>

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

Any kind of help would be appreciated. Many thanks for your time!

2
  • 2
    Not really clear to me what you want. You want one select box, or three select boxes? Commented Oct 29, 2020 at 9:41
  • @TKoL I want one select per each atribute product. The idea is to display them dynamically depending on the data response API. In this case there are three attributes to get the price. Commented Oct 29, 2020 at 9:56

1 Answer 1

1

If I understand your problem correctly, you could use Lodash's uniqBy method to easily get a list of unique values for each attribute:

    <select v-for="(val, attribute) in product.attributes" class="form-control">
        <option v-for="combination in uniqueValsForAttr(product.combinations, attribute)">
            {{ combination }}
        </option>
    </select>

    ...

    methods: {
        uniqueValsForAttr(combinations, attr) {
            return _.uniqBy(combinations, attr).map(item => item[attr]);
        }
    }

Then, when you have your selected values, you can find the price with something like this:

    getPrice(product, selections) {
        const { color, sex, size } = selections;
        const combination = product.combinations.find(comb => {
            return comb.color === color && comb.sex === sex && comb.size === size;
        });
        return combination.price;
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.