Reputation: 10882
I made a fetch API call in react.js and put it inside a variable defined within the function containing the fetch function. But how do I transfer this value to one of the variables in the state? I can get to the point where I console.log the variable, but still I'm not able to figure out how to update one of the state variables so that I can then display the retrieved data onto the page.
import React from 'react';
class Stock extends React.Component {
constructor(props) {
super(props);
this.state = {
stockInfo: '100'
}
}
componentDidMount() {
this.fetchStock();
}
fetchStock() {
const API_KEY = 'api key goes here';
let TimeInterval = '60min';
let StockSymbol = 'AMZN';
let API_Call = `https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=${StockSymbol}&interval=${TimeInterval}&outputsize=compact&apikey=${API_KEY}`;
let stockHistoryDatabase = {};
let stockHistoryDatabaseString;
fetch(API_Call)
.then(
function(response) {
return response.json();
}
)
.then(
function(data) {
console.log(data);
for (var key in data['Time Series (60min)']) {
// push the key value pair of the time stamp key and the opening value key paired together into an object with a key value pair data set storage.
var epochKeyTime = new Date(key);
epochKeyTime = epochKeyTime.getTime();
stockHistoryDatabase[epochKeyTime] = data['Time Series (60min)'][key]['1. open'];
}
console.log(stockHistoryDatabase);
stockHistoryDatabaseString = JSON.stringify(stockHistoryDatabase);
console.log(stockHistoryDatabaseString);
}
);
}
handleChange = () => {
this.setState({
stockInfo: 'hello'
});
}
render() {
return(
<div>
<h1>Stocks</h1>
<p>{this.state.stockInfo}</p>
<button onClick={this.handleChange}>Change</button>
</div>
);
}
}
export default Stock;
this is my code in entirety. I know how to change the state using a separate function that is called from a button click on the same page, but I'm unable to get the data stored in the variable 'stockHistoryDatabaseString' to replace the state 'stockInfo'.
Thank you for the help!
Upvotes: 1
Views: 5871
Reputation: 5734
Since you are calling fetchStock
after component is mounting. You can use arrow function as follows.
.then((data) => {
// use data here
this.setState({ ... }) // set you state
})
or if you are not comfortable using arrow function, then I believe you can create a function to handle the promise e.g. handleData
.then(this.handleData)
in class
// pseudo code
class YourClass extends React.Component {
componentDidMount() {
this.fetchStock()
}
handleData = (data) => {
// process your data and set state
}
fetchStock() {
// your API call
fetch(API_CALL).then(this.handleData);
}
render() {}
}
If you are invoking fetchStock
on user operation, such as button click, then you can provide appropriate context to fetchStock
by binding it to React class you've created as follows:
constructor() {
this.fetchStock = this.fetchStock.bind(this);
}
or there is another way to achieve the same (perhaps cleaner way):
fetchStock = () => {
}
Upvotes: 1
Reputation: 3059
I had a similar problem. My solution to this problem was to store this
context of react class into one variable and then use it in any scope below it.
fetchStock() {
const pointerToThis = this; // points to context of current react class
fetch(API_Call)
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log(pointerToThis); // you can use pointerToThis which in turn points to react class
});
}
Upvotes: 1
Reputation: 1039
First inside constructor add
this.fetchStock = this.fetchStock.bind(this);
Update fetchStock function like this:
fetchStock() {
const API_KEY = 'api key goes here';
let TimeInterval = '60min';
let StockSymbol = 'AMZN';
let API_Call = `https://www.alphavantage.co/queryfunction=TIME_SERIES_INTRADAY&symbol=${StockSymbol}&interval=${TimeInterval}&outputsize=compact&apikey=${API_KEY}`;
let stockHistoryDatabase = {};
let stockHistoryDatabaseString;
fetch(API_Call)
.then(response => response.json())
.then(data => {
for (var key in data['Time Series (60min)']) {
var epochKeyTime = new Date(key);
epochKeyTime = epochKeyTime.getTime();
stockHistoryDatabase[epochKeyTime] = data['Time Series (60min)'][key]['1. open'];
}
this.setState({stockInfo: stockHistoryDatabase})
//Set your state here.
stockHistoryDatabaseString = JSON.stringify(stockHistoryDatabase);
}
);
}
Upvotes: 1