I once wrote a very simple code to fetch&display data from certain api. Now that that API doesn't work anymore, I wanted to keep the code intact and make it display an error message that the API doesn't work.
async function getInfected() {
const api_url = //API Address that doesn't work anymore//;
const response = await fetch(api_url);
// console.log(response);
if (response.ok){
const data = await response.json();
const todayInfected = data.data[0][3];
const todayDeath = data.data[0][2];
document.getElementById('todayInfected').textContent = todayInfected;
document.getElementById('todayDeath').textContent = todayDeath;
} else {
const errorMessage = "Error! Can't fetch API!";
document.getElementsByClassName('nowp').textContent = errorMessage;
}
}
getInfected();
This code does nothing and console.log(response) also doesn't work. And unfortunately, I have very little understanding of fetch(). Any Ideas?
Related
let myHeaders = new Headers();
myHeaders.append("apikey", "QC9I9O0LPCFUfStGMD1h5CKcWN4Aehrk");
let requestOptions = {
method: 'GET',
redirect: 'follow',
headers: myHeaders
};
const endpoint = "https://api.apilayer.com/currency_data/live";
async function fetchRates(base = "USD") {
const res = await fetch(`${endpoint}?base=${base}`);
const rates = await res.json();
return rates;
}
async function convert(amount, from, to){
// first check if we even have the rates to convert from that currency
if (!ratesByBase[from]) {
console.log(`Oh no! we don't have ${from} to convert it ${to}, so let 's go get it`);
const rates = await fetchRates(from);
console.log(rates);
// store them for next time
ratesByBase[from] = rates;
}
}
Upon running above code it's saying no API key found in the requestcan you tell me how to include it properly
Upon running the command in the console
convert(100, 'CAD', 'USD')
it's returing not fetching the rates instead showing error API key not found in the request even i have included as per guidance of documentation in the APIlayer dashbaord Please guide me what i'm messing it will be highly appreciated.
I'm using Got to make requests to a Strapi API from Node, like so:
res.setHeader('Content-Type', 'application/json')
try {
const request = req.query.request
const decodedRequest = Buffer.from(request, 'base64').toString()
const api = process.env.API_URL ? process.env.API_URL.replace(/\/$/, '') : ''
const url = `${api}${decodedRequest}`
const response = await got.get(url)
const body = await got.get(url).json()
const headers = JSON.parse(JSON.stringify(response.headers))
res.status(200).json({
headers: headers,
data: body
})
} catch (e) {
res.status(500).json({})
}
This works but note that I have the request twice because if I do:
res.setHeader('Content-Type', 'application/json')
try {
const request = req.query.request
const decodedRequest = Buffer.from(request, 'base64').toString()
const api = process.env.API_URL ? process.env.API_URL.replace(/\/$/, '') : ''
const url = `${api}${decodedRequest}`
const response = await got.get(url)
const body = response.json()
const headers = JSON.parse(JSON.stringify(response.headers))
res.status(200).json({
headers: headers,
data: body
})
} catch (e) {
res.status(500).json({
error: e
})
}
it Just crashes and the e from the catch returns an empty error so I have no idea what's going on
I need the headers because the pagination info from Strapi is returned there:
This works because of the value you're awaiting. The conventional example:
const body = await got.get("...").json();
is equivalent to:
const res = got.get("...");
const body = await res.json();
// ^ note
but not:
const res = await got.get("...");
// ^ note
const body = res.json();
From the Promise API docs:
The main Got function returns a
Promise.
Although in order to support cancelation,
PCancelable is used
instead of pure Promise.
The json method is attached to this PCancelable object, not the value it resolves to. If you try to call it on the response, therefore, you get TypeError: res.json is not a function.
What you want is something like:
const res = await got.get("...");
const body = JSON.parse(res.body);
const headers = res.headers;
// ...
That said, if you're doing this for pagination reasons you could also look into their API for that.
I have a series of API calls I need to make in order to render a grid of image tiles for selection by the user. Right now it takes 3-5 seconds for the page to load and I think it's because I've accidentally added some extra loops, but I'm struggling to discern where the wasted flops are. This is technically a question about NFT data, but the problem is algorithmic not crypto related.
The call sequence is:
Call "Wallet" API to get all assets associated with an address - API doc
On success, call "Asset Metadata" API to get further info about each asset API Doc
Loop step 2 until all assets have a metadata response
This is my code that works (unless there is no assets associated with a wallet), but is just very slow. I'm sure there is a better way to handle this, but I'm struggling to see how. Thanks for your time!
// API Request
var myHeaders = new Headers();
myHeaders.append("X-API-Key", CENTER_API_KEY); //API Key in constants file
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
const [nftData, updatenftData] = useState();
const [apiState, updateapiState] = useState("init");
const [renderNFT, updaterenderNFT] = useState([]);
useEffect(() => {
const getData = async () => {
let resp = await fetch(walletAPICall, requestOptions);
let json = await resp.json()
updatenftData(json.items);
updateapiState("walletSuccess");
}
const getRender = async () => {
let nftTemp = [];
for (let i=0;i<nftData.length;i++) {
let tempAddress = nftData[i].address;
let tempTokenId = nftData[i].tokenId;
let resp = await fetch(`https://api.center.dev/v1/ethereum-mainnet/${tempAddress}/${tempTokenId}`, requestOptions)
let json = await resp.json()
// console.log(json);
nftTemp.push(json);
}
updaterenderNFT(nftTemp);
updateapiState("NftDataSuccess");
}
if (apiState=="init") {
getData();
}
else if (apiState=="walletSuccess") {
getRender();
}
}, [requestOptions]);
getRender fetches data items sequentially.
You should do it in parallel using Promise.all or Promise.allSettled
Something like this...
function fetchItem(item) {
const res = await fetch(item.url);
return res.json();
}
await Promise.all[...data.map(fetchItem)]
I'm just getting started with a simple project in node.js.
I'm trying to use Expo for the final app but get lots of dependency conflicts in the modules so was thinking of just calling the REST API via fetch. I have a test bed that works fine using the google-supplied modules, but I always get RecognitionAduio is not supplied as an error message via REST. As you can see in the attached code, the input file, coding etc are all identical.
any views?
async function getAudioTranscription() {
const fetch = require("node-fetch");
try {
var filename = 'C:/Users/SteveRist/Downloads/brooklyn.flac';
var encoding = 'FLAC';
var sampleRateHertz = 16000;
var languageCode = 'en-US';
const fs = require('fs');
const speech = require('#google-cloud/speech');
const client = new speech.SpeechClient();
console.log ('Setting REST config');
const config = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: languageCode,
};
console.log ('opening ', filename);
const audio = {
content: fs.readFileSync(filename).toString('base64'),
};
const request = {
config: config,
audio: audio,
};
// Detects speech in the audio file. This creates a recognition job that you
// can wait for now, or get its result later.
const [operation] = await client.longRunningRecognize(request);
// Get a Promise representation of the final result of the job
const [response] = await operation.promise();
const transcription = response.results
.map(result => result.alternatives[0].transcript)
.join('\n');
console.log(`Transcription: ${transcription}`);
const transcriptResponse = await fetch(
'https://speech.googleapis.com/v1/speech:recognize?key=xxx8', {
method: 'POST',
request: request
}
);
const data = await transcriptResponse.json();
console.log ('transcriptResponse Google returned' , data);
const userMessage = data.results && data.results[0].alternatives[0].transcript || "";
console.log (userMessage);
} catch (error) {
console.log("There was an error", error);
}
}
getAudioTranscription();
When calling the following method:
getLyrics: async function(song) {
const body = await this.getSongBody(song);
const lyrics = await cheerio.text(body('.lyrics'));
return lyrics;
}
as such:
genius.getLyrics('What a wonderful')
.then((res) => console.log(res))
.catch((err) => console.log(err.message));
Everything works fine and the lyrics of "What a wonderful world" by Louise Armstrong pops up in the console.
However, when I run the same code but without "await" in front of "cheerio.text..." sometimes the lyrics are produced and other times "undefined" shows up in the console. What has been making me scratch my head for a while now is that "cheerio.text..." does not return a promise (albeit "getSongBody" does), so to my understanding, there is no need to "wait" for it to finish.
I'm clearly missing something about async/await but have no idea what. Any help would be greatly appreciated!
Thanks
EDIT: Added a reproducible example as requested below:
const fetch = require('node-fetch');
const cheerio = require('cheerio');
// API
function geniusApi(token) {
this._token = token;
this._auth = {'Authorization': 'Bearer ' + this._token};
};
geniusApi.prototype = {
getSongURL : async function(search_keyword){
const res = await fetch('https://api.genius.com/search?q=' +
search_keyword,{headers: this._auth});
const body = await res.text();
const body_parsed = JSON.parse(body);
if (body_parsed.response.hits.length == 0){
console.log('No such song found');
throw Error('No such song found');
}
const url = body_parsed.response.hits[0].result.url;
return url;
},
getSongBody: async function (song){
const url = await this.getSongURL(song);
const response = await fetch(url);
const body = await response.text();
const body_parsed = cheerio.load(body);
return body_parsed;
},
getLyrics: async function(song) {
const body = await this.getSongBody(song);
const lyrics = cheerio.text(body('.lyrics'));
return lyrics;
}
}
// TEST EXAMPLE
const token =
'OTh1EYlsNdO1kELVwcevqLPtsgq3FrxfShIXg_w0EaEd8CHZrJWbWvN8Be773Cyr';
const genius = new geniusApi(token);
genius.getLyrics('What a wonderful')
.then((res) => console.log(res))
.catch((err) => console.log(err.message));
For anyone who ever stumbles upon the same issue, the problem in this case had nothing to do with async, promise or any other JS feature. It was merely a coincidence that the code had functioned correctly while using async, it later turned out that it didn't always work with async either.
The reason was simply that the Genius API that I was using to fetch the data, would return different source codes for identical API queries.
Two different source codes were returned, one contained a div called "lyrics" while the other did not. Therefore, sometimes the lyrics were found using cheerio, other times, they were not.