Reputation: 19
I'm attempting to learn react by creating a simple weather app which uses api requests to get the data. The api requires a location key which can be obtained through another function. this means i have to return and then pass the key along to the next function but I seem to be having some trouble doing this!
TypeError: _LocationKey__WEBPACK_IMPORTED_MODULE_3__.default.setLocation is not a function" is the error i am given when I attempt to run.
I'm assuming I made an error with how i am calling the functions as well as how the actual classes are structured. Any help would be appreciated!
//The main app
function App() {
//runs function to set api location key
new LocationKey();
LocationKey.setLocation('winnipeg');
//uses get location key to set weatherData
new Weather();
Weather.getWeatherData(LocationKey.getLocation());
//displays location and weather information
return (
<div className="body">
<LocationKey/>
<Weather/>
</div>
);
}
//The location key class
export class LocationKey extends Component{
state = {
locations: []
}
setLocation(name) {
axios.get('http://dataservice.accuweather.com/locations/v1/cities/search?apikey=oqAor7Al7Fkcj7AudulUkk5WGoySmEu7&q=' + name + '&language=en&details=false')
.then(res => {
const locations = res.data;
this.setState({ locations });
})
}
getLocation(){
return this.state.locations[0].Key;
}
render() {
return (
<ul>
{ this.state.locations.slice(0, 1).map(location => <li>{location.EnglishName}</li>)}
</ul>
)
}
}
export default LocationKey
//Weather Class
export class Weather extends Component{
state = {
weatherData: []
}
//issues command to find weather data from api using location key
getWeatherData(location) {
axios.get('http://dataservice.accuweather.com/forecasts/v1/daily/1day/' + location + '?apikey=oqAor7Al7Fkcj7AudulUkk5WGoySmEu7&language=en&details=false&metric=true%20HTTP/1.1')
.then(res => {
const weatherData = res.data;
this.setState({ weatherData });
})
}
render() {
return (
<ul>
{ this.state.weatherData.slice(0, 2).map(weather => <li>{weather.Headline.Text}</li>)}
{ this.state.weatherData.slice(0, 2).map(weather => <li>{weather.Headline.Category}</li>)}
{ this.state.weatherData.slice(0, 2).map(weather => <li>{weather.DailyForecasts.Maximum.Value}</li>)}
{ this.state.weatherData.slice(0, 2).map(weather => <li>{weather.DailyForecasts.Minimum.Value}</li>)}
</ul>
)
}
}
export default Weather
Upvotes: 2
Views: 748
Reputation: 7165
The issue lies with this line:
LocationKey.setLocation('winnipeg');
You instantiate a new instance of LocationKey
, but seeing as LocationKey
isn't a singleton and setLocation
is not a static method, you're trying to call an instance method in a static way.
Another potential issues is this line:
Weather.getWeatherData(LocationKey.getLocation());
As I said above, you instantiate a new instance of Weather
, but since it isn't doing anything and isn't assigned to anything, it gets immediately thrown away, so the following line has no effect on it.
I would suggest making App its own component and having it contain the state for the locations, then passing the locations array to each of the components.
class App extends React.Component {
state = {
locations: ['winnipeg'],
locationInput: ''
};
render() {
return (
<div>
<input value={this.state.locationInput} onChange={e => this.setState({ locationInput: e.target.value })} />
<button onClick={this.handleAddLocation}>add to locations</button>
<Weather locations={this.state.locations} />
<LocationKey locations={this.state.locations} />
</div>
)
}
handleAddLocation = () => {
if (this.state.locationInput === '') return;
this.setState({
locationInput: '',
locations: [...this.state.locations, this.state.locationInput]
});
};
}
class Weather extends React.Component {
static defaultProps = {
locations: []
}
render () {
return (
<div>
<h2>Weather Component</h2>
<h3>Locations provided:</h3>
<span>{this.props.locations.join(', ')}</span>
</div>
);
}
}
class LocationKey extends React.Component {
static defaultProps = {
locations: []
}
render () {
return (
<div>
<h2>LocationKey Component</h2>
<h3>Locations provided:</h3>
<span>{this.props.locations.join(', ')}</span>
</div>
);
}
}
ReactDOM.render( < App / > ,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app"></div>
In the above snippet, I set out to show you how props can be used and provided to child components.
I hope this can help and clarify some of this issues you've been having
Upvotes: 1