I deployed a React App, through Heroku, that uses the API at https://exchangeratesapi.io/ to convert currency. When I deploy to via Heroku, the error message in the HTML is "Error: Failed to fetch" and the Error itself is:
CurrencyUI.js:31 Mixed Content: The page at 'https://arcane-forest-12888.herokuapp.com/currency' was loaded over HTTPS, but requested an insecure resource 'http://api.exchangeratesapi.io/latest?access_key=dff081b889aae502999e19f12aab42e5&symbols=USD,ZAR,GBP,EUR'. This request has been blocked; the content must be served over HTTPS.
I tried implementing https://stackoverflow.com/a/67765239/13848021
//there's no way to disable mixed content using javascript but you can add this tag
< meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
//to your HTML to allow mixed content
But then it returns an undefined object. The API documentation makes it seem like I can simply change my BASE_URL to from http to https but this also returns an undefined object.
Here is my code:
import React, { useState, useEffect } from 'react'
import CurrencyInput from './CurrencyInput'
const BASE_URL = `http://api.exchangeratesapi.io/latest?access_key=dff081b889aae502999e19f12aab42e5&symbols=USD,ZAR,GBP,EUR`
const CurrencyUI = () => {
const [error, setError] = useState(null)
const [isLoaded, setIsLoaded] = useState(false)
const [currencies, setCurrencies] = useState([])
const [usdCurrency, setUsdCurrency] = useState()
const [zarCurrency, setZarCurrency] = useState()
const [gbpCurrency, setGbpCurrency] = useState()
const [eurCurrency, setEurCurrency] = useState()
const [amount, setAmount] = useState()
const [inAmount, setInAmount] = useState(true)
const [zarExRate, setZarExRate] = useState(false)
const [gbpExRate, setGbpExRate] = useState(false)
const [eurExRate, setEurExRate] = useState(false)
useEffect(() => {
fetch(BASE_URL)
.then(res => res.json())
.then(data => {
const currencyUSD = Object.keys(data.rates)[0]
const currencyZAR = Object.keys(data.rates)[1]
const currencyGBP = Object.keys(data.rates)[2]
const currencyEUR = Object.keys(data.rates)[3]
setIsLoaded(true)
setCurrencies([...Object.keys(data.rates)])
setUsdCurrency(data.rates[currencyUSD])
setZarCurrency(data.rates[currencyZAR])
setGbpCurrency(data.rates[currencyGBP])
setEurCurrency(data.rates[currencyEUR])
})
.catch(error => {
setIsLoaded(true)
setError(error)
})
}, [])
function handleFromAmountChange(e) {
setAmount(e.target.value)
setInAmount(true)
setZarExRate(false)
setGbpExRate(false)
setEurExRate(false)
}
function handleZarAmountChange(e) {
setAmount(e.target.value)
setInAmount(false)
setZarExRate(true)
setGbpExRate(false)
setEurExRate(false)
}
function handleGbpAmountChange(e) {
setAmount(e.target.value)
setInAmount(false)
setZarExRate(false)
setGbpExRate(true)
setEurExRate(false)
}
function handleEurAmountChange(e) {
setAmount(e.target.value)
setInAmount(false)
setZarExRate(false)
setGbpExRate(false)
setEurExRate(true)
}
if (inAmount) {
fromAmount = amount
zarAmount = ((amount / usdCurrency) * zarCurrency).toFixed(3)
gbpAmount = ((amount / usdCurrency) * gbpCurrency).toFixed(3)
eurAmount = ((amount / usdCurrency) * eurCurrency).toFixed(3)
} else if (zarExRate) {
zarAmount = amount
fromAmount = ((amount * usdCurrency) / zarCurrency).toFixed(3)
gbpAmount = ((amount * gbpCurrency) / zarCurrency).toFixed(3)
eurAmount = ((amount * eurCurrency) / zarCurrency).toFixed(3)
} else if (gbpExRate) {
gbpAmount = amount
fromAmount = ((amount * usdCurrency) / gbpCurrency).toFixed(3)
zarAmount = ((amount * zarCurrency) / gbpCurrency).toFixed(3)
eurAmount = ((amount * eurCurrency) / gbpCurrency).toFixed(3)
} else if (eurExRate) {
eurAmount = amount
fromAmount = ((amount * usdCurrency) / eurCurrency).toFixed(3)
gbpAmount = ((amount * gbpCurrency) / eurCurrency).toFixed(3)
zarAmount = ((amount * zarCurrency) / eurCurrency).toFixed(3)
}
if (error) {
return <div className="error">Error: {error.message}</div>
} else if (!isLoaded) {
return (
<div>
<h1>Loading...</h1>
</div>
)
} else {
return (
<div className="currency-ui">
<CurrencyInput
key={usdCurrency}
id={usdCurrency}
value={fromAmount}
onChangeAmount={handleFromAmountChange}
placeholder={currencies[0]}
/>
<CurrencyInput
key={zarCurrency}
id={zarCurrency}
value={zarAmount}
onChangeAmount={handleZarAmountChange}
placeholder={currencies[1]}
/>
<CurrencyInput
key={gbpCurrency}
id={gbpCurrency}
value={gbpAmount}
onChangeAmount={handleGbpAmountChange}
placeholder={currencies[2]}
/>
<CurrencyInput
key={eurCurrency}
id={eurCurrency}
value={eurAmount}
onChangeAmount={handleEurAmountChange}
placeholder={currencies[3]}
/>
</div>
)
}
}
export default CurrencyUI
None of the solutions I on here I have implemented solves my problem. Any ideas on what I can try?