Reputation: 1869
I am working with Vue 3 composition api and am retrieving weather data via async/await fetch
and I get a 200 response and the data in the request within the Chrome Dev Tools.
In the component receiving the data and making the call I have a provide
method and then I am inject
ing the data into another output component. The issue is in the inject
component. The value for the inject
ed variable is always null and does not update in the Vue Dev Tools so my data is never output to the screen. I went through the docs and the code is pretty much the same but I can't get it to work. Can anyone see an obvious issue?
Receiving Component
setup () {
async function getCurrentWeather () {
const response = await fetch(`${baseWeatherApiUrl}q=${userInput.value}`);
userInput.value = null;
return weatherData.value = await response.json();
}
const returnedWeatherData = reactive(weatherData);
provide('returnedWeatherData', returnedWeatherData);
return {
getCurrentWeather,
userInput,
weatherData
}
}
output component
setup () {
//Provide default of empty object in case no results exist
const weatherData = inject('returnedWeatherData');
console.log(weatherData) //No output even when making a new request to the weather api
return {
weatherData
}
}
As a separate test I tried to provide/inject
hardcoded values found in the docs but still geolocation
when injected remains null.
provide('geolocation', {
longitude: 90,
latitude: 135
})
const userGeolocation = inject('geolocation')
console.log(userGeolocation) // Nothing logged
return {
weatherData,
userGeolocation
}
Upvotes: 5
Views: 19619
Reputation: 4263
In my case it was importing inject
from "@vue/runtime-core" instead of "vue".
Of course provide
was imported from "vue".
Just leaving here, maybe it's gonna save someone an hour.
Upvotes: 5
Reputation: 138276
The provide
-ed argument should be the ref
itself (not wrapped in a reactive()
):
// Parent.vue
export default {
setup () {
const weatherData = ref()
// ❌
// const returnedWeatherData = reactive(weatherData);
// provide('returnedWeatherData', returnedWeatherData);
// ✅
provide('returnedWeatherData', weatherData);
}
}
And the child component's console.log()
in setup()
does not automatically get invoked again. You should wrap that call with watchEffect()
so that it does get called upon change to the ref
:
// Child.vue
import { inject, watchEffect } from 'vue'
export default {
setup () {
const weatherData = inject('returnedWeatherData')
// ❌
//console.log('new weatherData', weatherData.value)
// ✅
watchEffect(() => {
console.log('new weatherData', weatherData.value)
})
}
}
Upvotes: 8