Could someone provide me with a little bit of guidance on my class object and how to reference it in another in my project?
Here is my RequestAPI object - request-api.js (note: I understand that there isn't much going on in it yet, but I wanted to walk before I can run)
export class RequestApi {
constructor() {
this.apiBase = '../api';
}
fetch(url, options) {
var options = options || {};
return fetch(this.apiBase + url, options)
.then(_handleResponse, _handleNetworkError);
}
_handleResponse(response) {
if (response.ok) {
return response.json();
} else {
return response.json().then(function (error) {
throw error;
});
}
}
_handleNetworkError(error) {
throw {
msg: error.message
};
}
}
Here is the React Class component that i am trying to reference it in:
import React from 'react';
import { RequestApi } from '../../../../utils/request-api.js';
class UserLayout extends React.Component {
constructor() {
super();
this.state = {
users: [],
isLoading: true
};
this.addNewUser = this.addNewUser.bind(this);
this.editUser = this.editUser.bind(this);
this.deleteUser = this.deleteUser.bind(this);
}
componentDidMount() {
return RequestApi.fetch('/user')
.then(json => {
this.setState({
isLoading: false,
users: json
});
})
.catch(error => {
console.error(error.msg);
});
}
// more code here...
}
I get an error in my React Component Class object: Uncaught TypeError: _requestApi.RequestApi.fetch is not a function
Can anyone provide me with some insight/assistance?
Since fetch is not a static method, you need to create an instance of RequestApi prior to calling fetch on it:
componentDidMount() {
const api = new RequestApi();
return api.fetch('/user')
.then(json => {
this.setState({
isLoading: false,
users: json
});
})
.catch(error => {
console.error(error.msg);
});
}
Related
I have this bellow App.js code:
import React, { Component } from 'react';
import axios from 'axios'
class Axios extends Component {
constructor() {
super();
this.state = {
item : '',
}
}
componentDidMount() {
axios.get('https://restcountries.com/v3.1/capital/lima')
.then( response => {
const data = response.data.map(( data )=>{
this.setState({
item : data
});
});
})
.catch( error => {
alert( error );
});
}
prepare() {
console.log( this.state.item );
}
render() {
return (
<div>{this.prepare()}</div>
)
}
}
export default Axios;
My goal is to get the common name from this API: https://restcountries.com/v3.1/capital/lima
Now on componentDidMount() method, I need to set the API return data to the item state so that I can loop through using the prepare method.
But I don't have any idea how to set the API return array JSON data to the item state?
Update your state.item to a blank array.
constructor() {
super();
this.state = {
item : [],
}
}
In componentDidMount(), update the code to accept response :
componentDidMount() {
axios.get('https://restcountries.com/v3.1/capital/lima')
.then( response => {
this.setState({
item : response.data
});
})
.catch( error => {
alert( error );
});
}
In render(), you can use map on state.item and can loop on it.
render() {
return (
<div>{this.state.item.map(data,index)=>(
//some UI mapping to each `data` in `item` array
)}</div>
)
}
You just have to do assing response.data to item as:
Live Demo
componentDidMount() {
axios
.get("https://restcountries.com/v3.1/capital/lima")
.then((response) => {
this.setState({
item: response.data
})
})
.catch((error) => {
alert(error);
});
}
You should check this out.
import React, { Component } from "react";
import axios from "axios";
class Axios extends Component {
constructor() {
super();
this.state = {
item: []
};
}
componentDidMount() {
axios
.get("https://restcountries.com/v3.1/capital/lima")
.then((response) => {
this.setState({
item: response && response.data
});
})
.catch((error) => {
alert(error);
});
}
prepare() {
return <div>{console.log("Item", this.state.item)}</div>;
}
render() {
return <div>{this.prepare()}</div>;
}
}
export default Axios;
I am using axios to fetch weather information from openweathermap api in my react application. From the result of the api call (which is a json object), I can access some properties, for example data.base. But cant access data.coord.icon or data.weather[0].id etc.
data = [
coord: { lon: -0.1257,lat: 51.5085},
weather: [{ id: 721,
main: "Haze",
description: "haze",
icon: "50n"
}],
base: "stations"
]
I tried all the possible combinations. When trying to return data.coord, got the error Objects are not valid as a React child (found: object with keys {lon, lat}). If you meant to render a collection of children, use an array instead
But data.coord.lon gives lon of undefined
import React, { Component } from 'react';
import axios from 'axios';
export class WeatherInfo extends Component {
constructor(props) {
super(props)
this.state = {
isFetching: false,
data: [],
}
}
//function to fetch weather information
async getWeatherData(lat, lon) {
const weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.REACT_APP_WEATHER_KEY}`
try {
this.setState({ ...this.state, isFetching: true });
const response = await axios.get(weatherApi);
this.setState({ data: response.data, isFetching: false });
console.log(response.data)
} catch (error) {
console.log(error);
this.setState({ isFetching: false })
}
}
//function to get access to users location and to call getWeatherData function
weatherInit = () => {
const success = (position) => {
this.getWeatherData(position.coords.latitude, position.coords.longitude);
}
const error = () => {
alert('Unable to retrieve location.');
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
alert('Your browser does not support location tracking, or permission is denied.');
}
}
componentDidMount() {
this.weatherInit();
}
render() {
const { data } = this.state;
return (
<div>
<p>{data.name}</p>
</div>
)
}
}
export default WeatherInfo
Here is the example of how you can display various data returned by the API.
import React, {
Component
} from 'react';
import axios from 'axios';
export class WeatherInfo extends Component {
constructor(props) {
super(props)
this.state = {
isFetching: false,
data: [],
}
}
//function to fetch weather information
async getWeatherData(lat, lon) {
const weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.REACT_APP_WEATHER_KEY}`
try {
this.setState({ ...this.state,
isFetching: true
});
const response = await axios.get(weatherApi);
if(response.status===200){
//update state only if status is 200
this.setState({
data: response.data,
isFetching: false
});
console.log(response.data)
}
} catch (error) {
console.log(error);
this.setState({
isFetching: false
})
}
}
//function to get access to users location and to call getWeatherData function
weatherInit = () => {
const success = (position) => {
this.getWeatherData(position.coords.latitude, position.coords.longitude);
}
const error = () => {
alert('Unable to retrieve location.');
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
alert('Your browser does not support location tracking, or permission is denied.');
}
}
componentDidMount() {
this.weatherInit();
}
render() {
const {data} = this.state;
if (data) {
return (
<div >
//display coord
<p > {data.coord.lon} < /p>
<p > {data.coord.lat} < /p>
// display weather ids
{data.weather.map(item => {
return (
< p > { item.id } < /p>) })
}
< p > { data.name } < /p> < / div >
)
}
else {
return (<div>Data is loading or Not Found</div>)}
}
}
}
export default WeatherInfo
Necessarily you need to create an JSX element for each value you want to display.
Sorry, for formatting.
I'm making a call to a getTime function which returns the datetime, but for some reason the state I specify is not being updated, am I misunderstanding how this works? Do I need to await the result?
import * as React from 'react';
import {getTime} from '../utilities/time-helper'
export default class Landing extends React.Component {
constructor(props) {
super(props);
this.state = {
london: null,
paris: null
};
}
componentDidMount() {
this.setState({ london: getTime("Europe/London") });
this.setState({ paris: getTime("Europe/Paris") });
}
render() {
return (
<div>
<h1>London Time: {this.state.london}</h1>
<h1>Paris Time: {this.state.paris}</h1>
</div>
);
}
}
// time-helper.js
export function getTime(timezone) {
let url = 'http://worldtimeapi.org/api/timezone/' + timezone;
fetch(url)
.then(res => res.json())
.then((out) => {
return out.datetime
})
.catch(err => { throw err });
}
Yes, exactly, it's a fetch, so you gotta wait for the result and set the state only then, so you could do smth like:
componentDidMount() {
getTime('Europe/London')
.then((response) => this.setState({ london: response });
}
I'm new to react and I'm trying to pull and display data from randomuserapi. I've made the api call but when I run my app, I get the error below:
./src/App.js
Line 45: 'getData' is not defined no-undef
Here's my code below: The getData() method is where I make the api call. That method is now called in ComponentDidMount.
I also binded getData() to my constructor but I still get the error above.
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
people: []
}
this.getData = this.getData.bind(this);
}
getData() {
const promise = fetch('https://randomuser.me/api/?results=20')
.then(response => {
if (response.status >= 400) {
throw `Response Invalid ( ${response.status} )`;
return;
}
return response.json();
})
.then(({results}) => {
return results;
})
.catch(error => {
console.log(error);
});
return promise;
}
ComponenDidMount() {
getData()
.then(data => {
this.setState({
people: data
});
});
}
render() {
return (
<div>
<p>{this.state.people.results[0].gender}</p>
</div>
);
}
}
export default App;
I'm also using create-react-app from Github. Please some assistance will be helpful.
Thanks!
When you reference defined methods you need to say this so:
componenDidMount() {
this.getData()
.then(data => {
this.setState({
people: data
});
});
}
Try adding this. when calling your functions.
this.getData() inside componentDidMount
I've been making an app that is using the Google Sheet API and React/Redux.
If I hit the API from the component itself it works but I'm having an issue when it comes to fetch data through Redux.
This is code
Action creator:
export function fetchList() {
let data = null;
gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: FULL_LIST_ID,
range: RANGE
}).then((response) => {
data = response.result.values;
}, (response) => {
throw response.result.error.message;
});
return {
type: FETCH_LIST,
payload: data
}
}
Reducer:
export default function(state = INITIAL_STATE, action = {} ) {
switch (action.type) {
case FETCH_LIST:
return { ...state, list: action.payload };
default:
return state;
}
}
Component:
import React from 'react';
import { connect } from 'react-redux';
import { fetchList } from '../../actions/index.jsx';
export class DropdownList extends React.Component {
constructor(props) {
super(props);
this.state = { res: null }
// this._fetchList = this._fetchList.bind(this);
}
componentWillMount() {
// this should fetch the data from Redux
this.props.fetchList();
// so that when
console.log(this.props);
// I should see the values attached to the payload
// instead this is fetching the data from the API hit here
this._fetchList();
}
// Here I'm hitting the API from the component
_fetchList() {
gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: FULL_LIST_ID,
range: ['LIST!A1:B']
}).then((response) => {
this.setState({ res: response.result.values });
}, (response) => {
throw response.result.error.message;
});
}
_renderList() {
// this uses the values fetched locally
// return this.state.res.map((val, index) => {});
}
render() {
if (!this.state.res) {
return <div>Loading...</div>;
}
return (
<div>
{this._renderList()}
</div>
);
}
}
function mapStateToProps(state) {
return { list: state.list }
}
export default connect(mapStateToProps, { fetchList })(DropdownList);
Does anybody can help me out?
Thanks
OK, solved!
It was an issue of sync so I needed to use Redux-Thunk as a middleware in my Action Creator.