[Vuejs]-Vue.js build a view from an object using separate array

0👍

You have to pass the this.selected like this.hangOut[this.selected] as the following code

computed: {
    filter() {
      var result = {}; //create new emptly object to return
      var arr = this.hangOut[this.selected];
      for (var i = 0, len = arr.length; i < len; i++) {
        result[i]=arr[i];
      }
      return result;
    }
  }

Follow the fiddle https://jsfiddle.net/ty3ypmn0/9/

You have to access the computed property in your template {{filter}} and in js you can call like this.filter

0👍

Let’s take a look at jsFiddle:

I’ve refactored your code and made a computed method to handle selection:

listObjects() {
  let keys = Object.keys(this.persons).filter(key => this.hangOut[this.selected].indexOf(key) >= 0);

  let finalPeople = {};
  for(let i = 0; i < keys.length; i++) {
    let key = keys[i];
    finalPeople[key] = this.persons[key];
  }
  return finalPeople;
},

Let’s see what the code is saying:

let keys = Object.keys(this.persons).filter(key => this.hangOut[this.selected].indexOf(key) >= 0);

This line finds the objects which you provided inside an array inside hangOut, I’ve used Object.keys to retrieve keys of persons (which should be people :D) then I’ve filtered (Array.prototype.filter MDN reference) them to retrieve only selected objects (take a look at this.hangOut[this.selected].indexOf(key)…)

and finally added the items to the returned object and rendered them.

0👍

I add two others <p> to ilustrate what selectedInfos is returning.

First of all, when you are using the property computed in Vue think of variables that will change automatically if another variable inside your scope has changed (e.g when this.selected changes, selectedInfos will return something new and will updates).

I changed the "activeSelected" to this.selected to correctly keep tracking what you selected.

var vm = new Vue({
  el: '#app',
  data: {
    selected: "sometimes",
    selectOptions: {
      sometimes: "Sometimes",
      often: "Often",
      rarely: "Rarely"
    },
    persons: {
      joe: {
        height: 'Tall',
        eyes: 'blue',
        age: 30
      },
      jane: {
        height: 'Medium',
        eyes: 'green',
        age: 22
      },
      jerry: {
        height: 'short',
        eyes: 'brown',
        age: 33
      }
    },
    hangOut: {
      sometimes: ["joe", "jane"],
      often: ["jerry", "jane"],
      rarely: ["jerry", "joe"]
    }
  },
  computed: {
    selectedInfos() {
      var result = []; //create new emptly object to return
      arr = this.hangOut[this.selected];
      for (var i = 0; i < arr.length; i++) {
        result.push(this.persons[arr[i]])
      }
      return result;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
  <select v-model="selected">
    <option v-for="(frequency,key) in selectOptions" :value="key">{{frequency}}</option>
  </select>
  <ul>
    <li v-for="(person,key) in persons" :key="key">
      {{ person.eyes + " eyed " + key }}
    </li>
    <p>These two like to hangout: {{hangOut[selected][0]}} and {{hangOut[selected][1]}}
    </p>
    <p>Infos: {{selectedInfos}}
    </p>
    <p>OneInfo: {{selectedInfos[0]}}
    </p>
  </ul>
</div>

0👍

Like this ?
You just need a computed filtered array, filteredPersons. You can see that its inputs are persons, hangOut and ‘selected’, so whenever one of those changes, filteredPersons will be recalculated.

markup

<div id="app">
  <select v-model="selected">
    <option v-for="(frequency,key) in selectOptions" :value="key">{{frequency}}</option>
  </select>
  <ul>
    <li v-for="(person,key) in persons">
      {{ person.eyes + " eyed " + person.name }}
    </li>
    <p>These two like to hangout {{selected}}.</p>
    {{filteredPersons}}
  </ul>
</div>

js

var vm = new Vue({
  el: '#app',
  data: {
    selected: "sometimes",
    selectOptions: {
      sometimes: "Sometimes",
      often: "Often",
      rarely: "Rarely"
    },
    persons: [
       {name: 'joe',
        height: 'Tall',
        eyes: 'blue',
        age: 30
      },
       {name: 'jane',
        height: 'Medium',
        eyes: 'green',
        age: 22
      },
       {name: 'jerry',
        height: 'short',
        eyes: 'brown',
        age: 33
      }
    ],
    hangOut: {
      sometimes: ["joe", "jane"],
      often: ["jerry", "jane"],
      rarely: ["jerry", "joe"]
    }
  },
  computed: {
    filteredPersons(){
      return this.persons.filter( pers => this.hangOut[this.selected].indexOf(pers.name) + 1);
    }
  }
})

Leave a comment