Cameron White
Cameron White

Reputation: 245

Triggering several methods in Vue.js

I've created an application that takes an address or city and displays the most Favorited tweet at that location using Vuejs. I've written three methods for each thing that needs to happen.

First, I grab an auth key from a url fragment. Second, I pass the address to google's api to get cordinates. Finally, I use the key and location from the first two methods to make the final Api request to get the content I want.

As it stands I have three buttons that appear on the appropriate step and trigger their method with an @click. Is there a way to trigger a sequence of methods with @click? It seems like I may be able to use $emit to chain them together but I am new to developing on the web and don't fully understand what I've read so far.

Id like to just have one button do all three. My solution as it stands:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <title></title>
</head>

<body>
    <div id="app">
        <button @click="method1">button 1</button>
        <button @click="method2">button 2</button>
        <button @click="method3">button 3</button>
    </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js">
</script> 
<script>
new Vue({
    el: "#app",

    methods: {
        method1: function(){
            alert("first thing happened");
        },

        method2: function(){
            alert("second thing happend");
        },

        method3: function(){
            alert("third thing happened")
        }
    }
});

Upvotes: 0

Views: 2163

Answers (2)

user900362
user900362

Reputation:

I think it would be much more easy and intuitive to use a Promise(http://www.html5rocks.com/en/tutorials/es6/promises/). Promises have been around for a while now, but they are not supported by old IE (http://caniuse.com/#feat=promises). You can use a polyfill, though.

I started using them about 6 months ago and they are extremely powerful, and combined with vue-resource (https://github.com/vuejs/vue-resource) they are just amazing. Your code would look like this:

new Vue({
    el: "#app",

    methods: {
        method1: function(){
            this.$http(authCallUrl, data1)
            .then(function (response) {
               console.log('First call was successful', response);
               return this.$http(googleApiURL, data2);
            })
            .then(function (response) {
              console.log('Second call was successful', response);
              return this.$http(finalAPIRequestURL, data3);
            })
            .then(function (response) {
              console.log('Everything was top-notch', response);
            })
        }
    }
});

I know it seems like a lot of new things but believe me, Promises are gonna improve you life big times!

Cheers!

Upvotes: 4

Ito Pizarro
Ito Pizarro

Reputation: 1607

If you weren't relying on that asynchronous API call, you could have created a method that fired off all three sequentially and bound your @click to that. Because you are waiting on an AJAX call, though, the $emit() and custom event handling is probably the way to go. This will let you pass data between your methods, too (in case your API call is dependent on the result of your auth key extraction, et cetera).

new Vue({
  el: "#app",

  methods: {
    method1: function() {
      var resultOfMethod1 = "foo ";
      alert( "resultOfMethod1: " + resultOfMethod1 );
      this.$emit( "ready.method1", resultOfMethod1 );
    },

    method2: function( token ) {
      var resultOfMethod2 = token + "bar ";
      alert( "resultOfMethod2: " + resultOfMethod2 );
      this.$emit( "ready.method2", resultOfMethod2 );
    },

    method3: function( token ) {
      var resultOfMethod3 = token + "baz ";
      alert( "resultOfMethod3: " + resultOfMethod3 );
    }
  },
  events: {
    "ready.method1": function ( token ){
      this.method2( token );
    },
    "ready.method2": function ( token ){
      this.method3( token );
    }   
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js"></script>
<div id="app">
  <button @click="method1">button 1</button>
</div>

Upvotes: 1

Related Questions