DEV Community

Brian P. Hogan
Brian P. Hogan

Posted on • Edited on • Originally published at bphogan.com

Implementing "Who's in Space" with Vue

One of my favorite practice exercises from my book Exercises for Programmers is the "Who's In Space?" problem:

Did you know you can find out exactly who’s in space right now? The Open Notify API provides that information. Visit http://api.open-notify.org/astros.json to see not only how many people are currently in space but also their names and which spacecraft they’re on.

Create a program that pulls in this data and displays the information from this API in a tabular format.

I like this program for a few reasons. First, it's a little more challenging than "Hello World". Second, it's a chance to pull data from a remote source that doesn't require authentication, so I get to practice consuming data without having to worry about getting an API key. Finally, it's just plain fun.

Let's implement a solution to this in Vue.js. To fetch the data, we'll use Axios, a promise-based library for making web requests.

This will be a single HTML page; we don't need Vue's CLI tooling for this. We'll link to the Vue and Axios libraries in the HTML page.

Let's get started.

First, explore the API. When you make a request to http://api.open-notify.org/astros.json you'll see results that look like this:

{
  "people": [
    {
      "name": "Christina Koch",
      "craft": "ISS"
    },
...
  ],
  "number": 6,
  "message": "success"
}
Enter fullscreen mode Exit fullscreen mode

The API returns an object with three keys:

  1. people, containing the list of people in space
  2. number, containing the number of people in space
  3. message, containing a status message

Our app will take the people field and display it in an HTML table.

Create a new file called space.html and add an HTML template:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <title>Who's In Space</title>
  </head>
  <body>
    <div id="app">

    </div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The div with the ID of app is where you'll connect your Vue instance.

Within the div tags, add an HTML table for the results:

    <div id="app">
      <table>
        <tr>
          <th>Name</th>
          <th>Craft</th>
        </tr>
      </table>
Enter fullscreen mode Exit fullscreen mode

After the table, add a link to the Vue library itself:

...
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
</body>
Enter fullscreen mode Exit fullscreen mode

After that line, add a link to Axios:

  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.1/axios.js"></script>
Enter fullscreen mode Exit fullscreen mode

Now that the libraries are loaded, add a new script block and define a variable called url to hold the URL to the API:

  <script>
    const url = 'http://api.open-notify.org/astros.json';

  </script>

Enter fullscreen mode Exit fullscreen mode

Then below the const url line, add the following code to define a new Vue instance:

    new Vue({
      el: '#app',
      data () {
        return { people: null }
      },
      created () {
        // Fetching data here
      }

    })

Enter fullscreen mode Exit fullscreen mode

The el field connects, or "mounts" this Vue instance to the DOM element with the ID of app.

The data section returns an object with a field called people, which is set to null by default. The created section is where you'll fetch the data. created is one of Vue's lifecycle hooks. It fires before the Vue instance is actually connected to the DOM.

Within created, use Axios to make the request to the API and store the results in the people field of your Vue instance:

      created () {
       axios
          .get(url)
          .then(response => (this.people = response.data.people))
      }
    })
Enter fullscreen mode Exit fullscreen mode

Axios gets the results and stores them in response.data. Remember that the API's response contains three keys: people, number, and message. Since you only need people, you pull down only that part of the results using dot notation.

Now that you have the data, display the results. Use Vue's v-for directive to iterate over the results, creating table rows that display the person and the craft:

    <div id="app">
      <table>
        <tr>
          <th>Name</th>
          <th>Craft</th>
        </tr>
        <!-- add this -->
        <tr v-for="person of people">
          <td>{{ person.name }}</td>
          <td>{{ person.craft }}</td>
        </tr>
        <!-- add this -->
      </table>
    </div>
Enter fullscreen mode Exit fullscreen mode

The completed solution looks like this:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <title>Who's In Space</title>
  </head>
  <body>

    <div id="app">
      <table>
        <tr>
          <th>Name</th>
          <th>Craft</th>
        </tr>
        <tr v-for="person of people">
          <td>{{ person.name }}</td>
          <td>{{ person.craft }}</td>
        </tr>
      </table>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.1/axios.js"></script>

  <script>
    const url = 'http://api.open-notify.org/astros.json';

    new Vue({
      el: '#app',
      data () {
        return { people: null }
      },
      created () {
        axios
          .get(url)
          .then(response => (this.people = response.data.people))
      }
    })


  </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

When you view the page in your browser, you'll see the results:

The people in space right now

This implementation doesn't have any styling, but the functionality is there. In the full book, there are some additional challenges for this exercise, as well as 56 other exercises you can tackle in any language you choose.

Now that you have this working in Vue, try implementing it with another language or framework.

Top comments (2)

Collapse
 
erikweibust profile image
Erik Weibust

Fun example. I'm not really a js "person" but I've wanted to try vue.js and who doesn't like spaceships? However, I don't get the data rendering in my browser. When I turn on devtools I see some errors about axios not being defined. I typed up the example by hand once and tried copy/pasting your example. Neither worked. :( Any ideas?

Collapse
 
bphogan profile image
Brian P. Hogan

I wonder if you just happened to hit it on a day when there were some issues with Axios from the CDN, which is always a problem. I just copied the full example at the end of the tutorial to a new file and it worked without any issues.