João Saro
João Saro

Reputation: 543

Randomize data function (best practice)

I'm a complete beginner with Vue.js, but I'm trying to figure out to deal with functions on view components.

I saw a tutorial that mounted data on a component that divides sentences in two (so, two different fields), but I want to do call another function to randomize the sentences before returning data.

Sentence 1 - "This is" (part1) + "an example" (part2)
Sentence 2 - "Lorem ipsum dolor sit amet" (part1) + "consectetur adipiscing." (part2)
Sentence 3 - "Neque porro quisquam" (part1) + "consectetur, adipisci velit" (part2)

I will randomize with some conditions (part1 will match with a part 2 from other sentence). I already did this in vanilla javascript. What I want to know is, what is the best way to do this in Vue (without doing it inside mounted). How should I do that? Methods? Render function? Ready?

This code will return original sentences:

import axios from 'axios';

export default {

name: 'ProverbiosList',

data: function() {

  return  {
    proverbios: []
  }

},

mounted: function() {
  var _self = this;

  axios.get('http://localhost:8888/api/proverbios').then(function (response) {

    _self.proverbios = response.data;

    })
  }
}

Upvotes: 1

Views: 869

Answers (1)

Bert
Bert

Reputation: 82489

I would almost always do this in a computed value. Manipulating data is one of the primary reasons computed values exist.

computed:{
  randomProverbs(){
    return this.randomize(this.proverbios)
  }
},

Note that this computed value is using methods defined on the instance where it makes sense.

Here is a working example.

console.clear()

const proverbs = [
  "Actions speaks louder than words.",
  "Give someone an inch, they will take a mile.",
  "Let bygones be bygones",
  "The shoe is on the other foot.",
  "When it rains, it pours.",
  "A friend in need is a friend indeed.",
  "A watched pot never boils.",
  "Absence makes the heart grow fonder.",
  "All's fair in love and war.",
  "All's well that ends well.",
  "Beggars can't be choosers.",
  "Better late than never.",
  "Better safe than sorry.",
  "Blood is thicker than water.",
  "Close, but no cigar.",
  "Crime doesn't pay.",
  "Curiosity killed the cat.",
  "Don't count your chickens before they hatch.",
  "Don't put all your eggs in one basket.",
  "Early to bed, early to rise makes a man healthy, wealthy, and wise.",
  "Easy come, easy go.",
  "Every cloud has a silver lining.",
  "Every dog has its day.",
  "Honesty is the best policy.",
  "If at first you don't succeed, try, try again.",
  "It takes two to tango."
]

const ProverbsList = {
  name: 'ProverbiosList',
  template:`
    <div>
      <span v-if="this.proverbios.length === 0">Loading proverbs...</span>
      <ul v-else>
        <li v-for="proverb in randomProverbs">{{proverb}}</li>
      </ul>
    </div>
  `,
  computed:{
    randomProverbs(){
      return this.randomize(this.proverbios)
    }
  },
  methods:{
    randomize(strings){
      const reducer = (acc, proverb) => {
        let midString = proverb.length / 2
        acc.start.push(proverb.slice(0, proverb.indexOf(' ', midString)))
        acc.end.push(proverb.slice(proverb.indexOf(' ', midString)))
        return acc
      }
      
      let parts = strings.reduce(reducer,{start:[], end:[]})
      parts.start = this.shuffle(parts.start)
      parts.end = this.shuffle(parts.end)
      
      return parts.start.map((v,i) => `${v} ${parts.end[i]}`)    
    },
    // from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
    shuffle(array) {
      var currentIndex = array.length, temporaryValue, randomIndex;
      while (0 !== currentIndex) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }

      return array;
    }
  },
  data: function() {
    return {
      proverbios: []
    }
  },
  mounted: function() {
    // simulate an ajax request
    setTimeout(() => this.proverbios = proverbs, 250)
  }
}

new Vue({
  el: "#app",
  components:{ProverbsList}
 })
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>

<div id="app">
  <proverbs-list></proverbs-list>
</div>

Upvotes: 3

Related Questions