1

I'm new to Vue and am working on an app to get the weather from a weather api.
The code below works if I leave axios.get() in Content.vue as it is below.
I want to move it to a separate file (WeatherAPI.js) and call it from there. If I comment out axois.get() call in Content.vue and uncomment this.todaysWeather = WeatherAPI.returnTodaysWeather(); it doesn't work. I do see the data logged to the console from WeatherAPI.js so it's getting it, but it doesn't seem to return it correctly. I see undefined in the console log from Content.vue.

Content.vue

<template>
<div class="container-fluid">
    <div class="row answerRow text-center">
        <div class="col">
        </div>
    </div>
    <div class="row">
        <div class="col">
            <weather-today :todaysWeather="todaysWeather"></weather-today>
        </div>
        <div class="col">
            Column2
        </div>
    </div>
</div>
</template>

<script>
import Today from '../weather/Today.vue'
import WeatherAPI from '../data/WeatherAPI.js'
import axios from 'axios'
const apiURL = "http://api.openweathermap.org/data/2.5/weather";
const apiKey = "MyKeyHere";
const zipCode = "11111,us";
const dailyWeatherUrl = apiURL + "?zip=" + zipCode + "&appid=" + apiKey;
export default {
    mounted(){
        this.getTodaysWeather();
        console.log(this.todaysWeather)
    },
    data () {
        return {
            todaysWeather: {name: "testname"}
        }
    },
    components: {
        'weather-today': Today
    },
    methods: {
        getTodaysWeather () {
            //this.todaysWeather = WeatherAPI.returnTodaysWeather();            
            axios.get(dailyWeatherUrl)
                .then((response) => {
                    console.log(response.data);
                    this.todaysWeather = response.data;
                })
                .catch(function (error) {
                    console.log(error);
                });


        }
    }
}
</script>

<style>
.answerRow{
    background-color: yellow;
}
</style>

Today.vue

<template>
    <div class="container row1">
        <div class="row">
            <div class="col">
                <h2>Todays Weather</h2>
            </div>
        </div>            
        <div class="row">
            <div class="col">
                City: {{ todaysWeather.name }}
            </div>
        </div>   
    </div>
</template>

<script>
import WeatherAPI from '../data/WeatherAPI.js'
export default {
    props: ['todaysWeather'],
    mounted() {
        console.log(this.todaysWeather)
    }    
}
</script>

<style>
.row1{
    background-color: #3498DB;
}
</style>

WeatherAPI.js

const apiURL = "http://api.openweathermap.org/data/2.5/weather";
const apiKey = "MyKeyHere";
const zipCode = "11111,us";
const dailyWeatherUrl = apiURL + "?zip=" + zipCode + "&appid=" + apiKey;

import axios from 'axios';
export default {   
  data(){
    return {
      todaysWeather: {}
    }
  },
    returnTodaysWeather () {
        axios.get(dailyWeatherUrl)
        .then((response) => {
          console.log(response.data);
          this.todaysWeather = response.data;
          console.log(this.todaysWeather);
          return this.todaysWeather;
        })
        .catch(function (error) {
          console.log(error);
        });
    }


}

1 Answer 1

3

Your WeatherAPI.js file really shouldn't have anything to do with Vue, it should just be a file that contains methods that interact with the weather API.

WeatherAPI.js

const apiURL = "http://api.openweathermap.org/data/2.5/weather";
const apiKey = "MyKeyHere";
const zipCode = "11111,us";
const dailyWeatherUrl = apiURL + "?zip=" + zipCode + "&appid=" + apiKey;

import axios from 'axios';

export function returnTodaysWeather () {
  return axios.get(dailyWeatherUrl)
           .then(response => response.data)
}

Notice that this function returns a promise. We will use that later. Also, this code exports the function directly. If you wanted to, you could export an object that has multiple functions interacting with the API in different ways.

Now in Content.vue all you need to do is import the weather API you want to use.

Content.vue

// import the returnTodaysWeather function from the api file
import { returnTodaysWeather } from '../data/WeatherAPI.js'

export default {
    mounted(){
        this.getTodaysWeather();
        console.log(this.todaysWeather)
    },
    data () {
        return {
            todaysWeather: {name: "testname"}
        }
    },
    components: {
        'weather-today': Today
    },
    methods: {
        getTodaysWeather () {
            // The API returns a promise. In the callback from the 
            // promise, we can set the Vue's data with the results
            // of the call to the API
            returnTodaysWeather().then(weather => this.todaysWeather = weather)           
        }
    }
}

I removed the error handling, but in production you would obviously want to catch errors from the API.

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.