Skip to content

Commit 6532979

Browse files
committed
FMP API changed its free tier account policy. So I had to change the way I am fetching chart data and stocks/forex quotes.
1 parent 6edb270 commit 6532979

File tree

6 files changed

+112
-110
lines changed

6 files changed

+112
-110
lines changed

.eslintcache

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/components/home-market-cards/HomeMarketCards.jsx

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import React from "react";
2-
import { useSelector, useDispatch } from "utils/react-redux-hooks";
3-
import Slider from "react-slick";
1+
import React from 'react';
2+
import { useSelector, useDispatch } from 'utils/react-redux-hooks';
3+
import Slider from 'react-slick';
44

5-
import { setMarketDetail, fetchRating } from "redux/actions/chart";
5+
import { setMarketDetail, fetchRating } from 'redux/actions/chart';
66

7-
import MarketCardsChart from "components/market-cards-chart/MarketCardsChart";
8-
import { MarketCards, Placeholder } from "./HomeMarketCards.styles";
7+
import MarketCardsChart from 'components/market-cards-chart/MarketCardsChart';
8+
import { MarketCards, Placeholder } from './HomeMarketCards.styles';
99

10-
import "slick-carousel/slick/slick.css";
11-
import "slick-carousel/slick/slick-theme.css";
10+
import 'slick-carousel/slick/slick.css';
11+
import 'slick-carousel/slick/slick-theme.css';
1212

1313
const HomeMarketCards = () => {
1414
const { forex, homeChartData } = useSelector((state) => state.chart);
@@ -20,7 +20,7 @@ const HomeMarketCards = () => {
2020
slidesToScroll: 1,
2121
autoplay: true,
2222
speed: 8000,
23-
cssEase: "linear",
23+
cssEase: 'linear',
2424
responsive: [
2525
{
2626
breakpoint: 1024,
@@ -48,39 +48,41 @@ const HomeMarketCards = () => {
4848

4949
return (
5050
<Slider {...settings}>
51-
{forex.map((data, index) => (
52-
<div key={index}>
53-
<MarketCards
54-
to={`/details/${data.symbol.toLowerCase()}`}
55-
percentage={data.changesPercentage}
56-
onClick={() => {
57-
dispatch(setMarketDetail(data));
58-
dispatch(fetchRating(data.symbol));
59-
}}
60-
>
61-
<div>
62-
<h1>{data.symbol.split("^").join("")}</h1>
63-
<h1
64-
style={{
65-
fontWeight: "normal",
66-
fontSize: "var(--size-sub-menu)",
51+
{forex.length > 5
52+
? forex.map((data, index) => (
53+
<div key={index}>
54+
<MarketCards
55+
to={`/details/${data.symbol.toLowerCase()}`}
56+
percentage={data.changesPercentage}
57+
onClick={() => {
58+
dispatch(setMarketDetail(data));
59+
dispatch(fetchRating(data.symbol));
6760
}}
6861
>
69-
$ {data.price.toFixed(2)}
70-
</h1>
71-
<h2> {data.changesPercentage}%</h2>
72-
</div>
62+
<div>
63+
<h1>{data.symbol.split('^').join('')}</h1>
64+
<h1
65+
style={{
66+
fontWeight: 'normal',
67+
fontSize: 'var(--size-sub-menu)',
68+
}}
69+
>
70+
$ {data.price.toFixed(2)}
71+
</h1>
72+
<h2> {data.changesPercentage}%</h2>
73+
</div>
7374

74-
{homeChartData.length > 5 ? (
75-
<MarketCardsChart index={index} />
76-
) : (
77-
// I added div here for first chart to wait for homeChartData
78-
// Second, so that chart wouldnt glitch
79-
<Placeholder />
80-
)}
81-
</MarketCards>
82-
</div>
83-
))}
75+
{homeChartData.length > 5 ? (
76+
<MarketCardsChart index={index} />
77+
) : (
78+
// I added div here for first chart to wait for homeChartData
79+
// Second, so that chart wouldn't glitch
80+
<Placeholder />
81+
)}
82+
</MarketCards>
83+
</div>
84+
))
85+
: null}
8486
</Slider>
8587
);
8688
};

src/components/home/Home.jsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import React from "react";
2-
import { useSelector, useDispatch } from "utils/react-redux-hooks";
3-
import { Route, Switch } from "react-router-dom";
1+
import React from 'react';
2+
import { useSelector, useDispatch } from 'utils/react-redux-hooks';
3+
import { Route, Switch } from 'react-router-dom';
44

55
import {
66
fetchTopStories,
77
fetchMostPopular,
88
changeHeader,
9-
} from "redux/actions/news";
9+
} from 'redux/actions/news';
1010

11-
import Loading from "components/loading/Loading";
12-
import ErrorFallback from "components/error-fallback/ErrorFallback";
13-
import StoryComponents from "components/story-components/StoryComponents";
14-
import MarketComponents from "components/market-components/MarketComponents";
15-
import MarketDetails from "components/market-details/MarketDetails";
16-
import ResponsiveNav from "components/responsive-nav/ResponsiveNav";
17-
import SearchResults from "components/search-results/SearchResults";
11+
import Loading from 'components/loading/Loading';
12+
import ErrorFallback from 'components/error-fallback/ErrorFallback';
13+
import StoryComponents from 'components/story-components/StoryComponents';
14+
import MarketComponents from 'components/market-components/MarketComponents';
15+
import MarketDetails from 'components/market-details/MarketDetails';
16+
import ResponsiveNav from 'components/responsive-nav/ResponsiveNav';
17+
import SearchResults from 'components/search-results/SearchResults';
1818

19-
import { topics } from "components/story-topic-headers/StoryTopicHeaders";
19+
import { topics } from 'components/story-topic-headers/StoryTopicHeaders';
2020

2121
const Home = () => {
2222
const { header, loadingNews, popular, width } = useSelector(
@@ -32,7 +32,7 @@ const Home = () => {
3232
// then the app will show the client the relevant results
3333
if (
3434
topics.includes(path.slice(1).charAt(0).toUpperCase() + path.slice(2)) ||
35-
path === "/"
35+
path === '/'
3636
) {
3737
dispatch(changeHeader(path.slice(1)));
3838
}
@@ -49,7 +49,7 @@ const Home = () => {
4949
<ResponsiveNav />
5050
<Switch>
5151
{loadingNews ? (
52-
<Loading height={width < 1024 ? "600px" : "400px"} />
52+
<Loading height={width < 1024 ? '600px' : '400px'} />
5353
) : (
5454
<Route
5555
path={`/${header.toLowerCase()}`}

src/components/market-components/MarketComponents.jsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import React from "react";
2-
import { useDispatch, useSelector } from "utils/react-redux-hooks";
3-
import { ErrorBoundary } from "react-error-boundary";
1+
import React from 'react';
2+
import { useDispatch, useSelector } from 'utils/react-redux-hooks';
3+
import { ErrorBoundary } from 'react-error-boundary';
44

5-
import { fetchHomeChart, fetchForex } from "redux/actions/chart";
6-
import fetchMarketTypes from "utils/fetch-market-types";
5+
import { fetchHomeChart, fetchForex } from 'redux/actions/chart';
6+
import fetchMarketTypes from 'utils/fetch-market-types';
77

8-
import ErrorFallback from "components/error-fallback/ErrorFallback";
9-
import Loading from "components/loading/Loading";
10-
import HomeMarketCards from "components/home-market-cards/HomeMarketCards";
8+
import ErrorFallback from 'components/error-fallback/ErrorFallback';
9+
import Loading from 'components/loading/Loading';
10+
import HomeMarketCards from 'components/home-market-cards/HomeMarketCards';
1111

1212
import {
1313
MarketComponentsContainer,
1414
MarketHeaderContainer,
1515
MarketTitle,
1616
MarketMenu,
17-
} from "./MarketComponents.styles";
17+
} from './MarketComponents.styles';
1818

1919
// First, I made market types array, the ones that I want to show in home page
2020
export const marketTypes = [
21-
"Indexes",
22-
"Crypto",
23-
"Forex",
24-
"Stocks",
25-
"Commodities",
21+
'Indexes',
22+
'Crypto',
23+
'Forex',
24+
'Stocks',
25+
'Commodities',
2626
];
2727

2828
const MarketComponents = () => {

src/redux/actions/chart.js

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
import axios from "axios";
2-
3-
export const FETCH_FOREX_SUCCESS = "FETCH_FOREX_SUCCESS";
4-
export const FETCH_CHART_ERROR = "FETCH_CHART_ERROR";
5-
export const SET_LOADING = "SET_LOADING";
6-
export const SET_LOADING_TRUE = "SET_LOADING_TRUE";
7-
export const CHANGE_MARKET_TYPE = "CHANGE_MARKET_TYPE";
8-
export const CHANGE_MARKET_NAME = "CHANGE_MARKET_NAME";
9-
export const SET_MARKET_DETAIL = "SET_MARKET_DETAIL";
10-
export const SET_CHART_DATA = "SET_CHART_DATA";
11-
export const CLEAN_CHART_DATA = "CLEAN_CHART_DATA";
12-
export const SET_CHART_TIME_FRAME = "SET_CHART_TIME_FRAME";
13-
export const SET_RATING = "SET_RATING";
14-
export const SET_HOME_CHART_DATA = "SET_HOME_CHART_DATA";
15-
export const CLEAN_STATE = "CLEAN_STATE";
16-
export const GET_SEARCH_RESULTS = "GET_SEARCH_RESULTS";
17-
export const SET_SEARCH_MARKET_DETAIL = "SET_SEARCH_MARKET_DETAIL";
18-
export const CLEAR_SEARCH_RESULTS = "CLEAR_SEARCH_RESULTS";
19-
export const OPEN_SEARCH_MODAL = "OPEN_SEARCH_MODAL";
20-
export const CLOSE_SEARCH_MODAL = "CLOSE_SEARCH_MODAL";
21-
export const TOGGLE_SEARCH_MODAL = "TOGGLE_SEARCH_MODAL";
1+
import axios from 'axios';
2+
3+
export const FETCH_FOREX_SUCCESS = 'FETCH_FOREX_SUCCESS';
4+
export const FETCH_CHART_ERROR = 'FETCH_CHART_ERROR';
5+
export const SET_LOADING = 'SET_LOADING';
6+
export const SET_LOADING_TRUE = 'SET_LOADING_TRUE';
7+
export const CHANGE_MARKET_TYPE = 'CHANGE_MARKET_TYPE';
8+
export const CHANGE_MARKET_NAME = 'CHANGE_MARKET_NAME';
9+
export const SET_MARKET_DETAIL = 'SET_MARKET_DETAIL';
10+
export const SET_CHART_DATA = 'SET_CHART_DATA';
11+
export const CLEAN_CHART_DATA = 'CLEAN_CHART_DATA';
12+
export const SET_CHART_TIME_FRAME = 'SET_CHART_TIME_FRAME';
13+
export const SET_RATING = 'SET_RATING';
14+
export const SET_HOME_CHART_DATA = 'SET_HOME_CHART_DATA';
15+
export const CLEAN_STATE = 'CLEAN_STATE';
16+
export const GET_SEARCH_RESULTS = 'GET_SEARCH_RESULTS';
17+
export const SET_SEARCH_MARKET_DETAIL = 'SET_SEARCH_MARKET_DETAIL';
18+
export const CLEAR_SEARCH_RESULTS = 'CLEAR_SEARCH_RESULTS';
19+
export const OPEN_SEARCH_MODAL = 'OPEN_SEARCH_MODAL';
20+
export const CLOSE_SEARCH_MODAL = 'CLOSE_SEARCH_MODAL';
21+
export const TOGGLE_SEARCH_MODAL = 'TOGGLE_SEARCH_MODAL';
2222

2323
export const toggleSearchModal = () => ({
2424
type: TOGGLE_SEARCH_MODAL,
@@ -107,22 +107,22 @@ export const fetchChartError = (error) => ({
107107
payload: error,
108108
});
109109

110-
export const fetchForex = (market) => async (dispatch) => {
110+
export const fetchForex = (markets) => async (dispatch) => {
111+
const marketArray = markets.split(',').sort();
112+
let forexList = [];
113+
114+
// FMP API changed its services. Before I could make a batch request
115+
// for getting quites. Now they dont let free account do it.
116+
// So I had to find a workaround for that with looping the free endpoint.
111117
try {
112-
const response = await axios.get(
113-
`https://financialmodelingprep.com/api/v3/quote/${market}?apikey=${process.env.REACT_APP_CHART_KEY}`
114-
);
115-
const data = await response.data;
116-
// FinancialModel API doesn't send error if it's about limit reach.
117-
// In that sense, they send an error message with 200 status. Weird.
118-
// Thats why I am catching that error here and dispatching it.
119-
if (data.length) {
120-
return data.length === 1
121-
? [dispatch(setSearchMarketDetail(data))]
122-
: [dispatch(fetchForexSuccess(data))];
123-
} else {
124-
return dispatch(fetchChartError(data));
118+
for (let market of marketArray) {
119+
const response = await axios.get(
120+
`https://financialmodelingprep.com/api/v3/quote/${market}?apikey=${process.env.REACT_APP_CHART_KEY}`
121+
);
122+
const data = await response.data;
123+
forexList.push(data);
125124
}
125+
return dispatch(fetchForexSuccess(forexList));
126126
} catch (error) {
127127
return dispatch(fetchChartError(error));
128128
}
@@ -161,12 +161,13 @@ Plus, its so clean!
161161
Yet another homerun for me! 😁😎
162162
*/
163163
export const fetchHomeChart = (symbols) => async (dispatch) => {
164-
const symbolsArray = symbols.split(",").sort();
164+
const symbolsArray = symbols.split(',').sort();
165165

166166
let charts = [];
167167

168168
dispatch(cleanState());
169169
dispatch(setLoadingTrue());
170+
170171
try {
171172
for (let symbol of symbolsArray) {
172173
const response = await axios.get(
@@ -175,7 +176,6 @@ export const fetchHomeChart = (symbols) => async (dispatch) => {
175176
const data = await response.data;
176177
charts.push(data);
177178
}
178-
179179
return [dispatch(setHomeChartData(charts)), dispatch(setLoading())];
180180
} catch (error) {
181181
return dispatch(fetchChartError(error));

src/redux/reducers/chart.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import * as ChartActions from "redux/actions/chart";
1+
import * as ChartActions from 'redux/actions/chart';
22

33
const initialState = {
44
loadingChart: false,
55
forex: [],
66
errorChart: null,
77
// Indexes (market type index's symbols) are first to load.
8-
marketType: "%5EGSPC,%5ERUA,%5EDJI,%5ENDX,%5EN225,%5EFTSE",
9-
marketName: "Indexes",
8+
marketType: '%5EGSPC,%5ERUA,%5EDJI,%5ENDX,%5EN225,%5EFTSE',
9+
marketName: 'Indexes',
1010
marketDetail: {},
1111
chartData: [],
12-
chartTimeFrame: "1hour",
12+
chartTimeFrame: '1hour',
1313
rating: [],
1414
homeChartData: [],
1515
searchResults: [],
@@ -21,7 +21,7 @@ const chartReducer = (state = initialState, action) => {
2121
case ChartActions.FETCH_FOREX_SUCCESS:
2222
return {
2323
...state,
24-
forex: action.payload,
24+
forex: action.payload.flat(),
2525
};
2626
case ChartActions.FETCH_CHART_ERROR:
2727
return {

0 commit comments

Comments
 (0)