How to display API information on a page - javascript

I am working on creating a simple page that displays current free game giveaways using this API. https://gamerpower.p.rapidapi.com/api/giveaways?type=game&sort-by=popularity
However, I am still very new at working with APIs and am not sure if what I've been searching for is the right direction. The sources that I've been looking at haven't made much sense, and any examples I've tried to follow still result in an Uncaught Reference error telling me that the variable I am trying to use isn't defined.
Here is my very messy and basic code.
const gamesList = {
method: 'GET',
headers: {
'X-RapidAPI-Key': '<API-KEY>',
'X-RapidAPI-Host': 'gamerpower.p.rapidapi.com'
}
};
fetch('https://gamerpower.p.rapidapi.com/api/giveaways?type=game&sort-by=popularity', gamesList)
.then(response => response.json())
.then(data => console.log(data.gamesList))
let games=data
document.querySelector('h2').innerText=data.gamesList.title
.catch(err => console.error(err));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="This is where your description goes">
<meta name="keywords" content="one, two, three">
<title>Game Giveaways</title>
<!-- external CSS link -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Current Game Giveaways</h1>
<button type="button" name="button">Get Burger</button>
<h2>Games</h2>
<img src="" alt="">
<h3>Description</h3>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
I'm sure I am just missing something incredibly simple, but after working on it longer than I want to admit, I still can't wrap my head around where I'm going wrong.

Note: In the future, do not share your API key with anyone.
You need to understand the response from the API call. I will demonstrate this to you using TypeScript types.
The response of the /api/giveaways call is a Giveaway[] ("object array" or "array of objects").
Here is a Giveaway object:
interface Giveaway {
description: string,
end_date: string, // 'YYYY-MM-DD HH:mm:ss' or 'N/A'
gamerpower_url: string, // URL
id: number,
image: string, // Resource URI
instructions: string, // HTML
open_giveaway: string, // URL
open_giveaway_url: string, // URL
platforms: string, // CSV
published_date: string, // 'YYYY-MM-DD HH:mm:ss' or 'N/A'
status: string, // e.g. 'Active'
thumbnail: string, // Resource URI
title: string,
type: string, // e.g. 'Game'
users: number, // user count
worth: string // Currency in USD
}
Now that we understand the response of the API call, we know that we are dealing with an array of objects. Make sure that your second .then call is a function that contains all your success logic.
fetch(url, options)
.then((response) => response.json()) // parse JSON response
.then((data) => {
// do stuff with data (in this case an object[])
})
.catch((err) => console.error(err)); // handle errors
Here is a "working" demo. All you need to do is supply a valid API key.
const apiHost = 'gamerpower.p.rapidapi.com';
const apiBaseUrl = `https://${apiHost}/api`
const apiKey = '<API-KEY>';
const defaultRequestConfig = {
method: 'GET',
headers: {
'X-RapidAPI-Key': apiKey,
'X-RapidAPI-Host': apiHost
}
};
const endpoint = `${apiBaseUrl}/giveaways?type=game&sort-by=popularity`;
fetch(endpoint, defaultRequestConfig)
.then(response => response.json())
.then(gamesList => {
const ul = document.createElement('UL');
gamesList.forEach(({ title }) => {
ul.append(Object.assign(document.createElement('LI'), { innerText: title }));
});
document.querySelector('h2').after(ul);
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" rel="stylesheet"/>
<h1>Current Game Giveaways</h1>
<button type="button" name="button">Get Burger</button>
<h2>Games</h2>
<img src="" alt="">
<h3>Description</h3>
Here is the async/await version:
(async() => {
const endpoint = `${apiBaseUrl}/giveaways?type=game&sort-by=popularity`;
const gamesList = await fetch(endpoint, defaultRequestConfig)
.then(response => response.json());
const ul = document.createElement('UL');
gamesList.forEach(({ title }) => {
ul.append(Object.assign(document.createElement('LI'), { innerText: title }));
});
document.querySelector('h2').after(ul);
})();

The code that uses data needs to be inside the .then() callback. You have it after the callback.
fetch('https://gamerpower.p.rapidapi.com/api/giveaways?type=game&sort-by=popularity', gamesList)
.then(response => response.json())
.then(data => {
console.log(data.gamesList);
document.querySelector('h2').innerText = data.gamesList.title;
})
.catch(err => console.error(err));

Related

How to call multiple APIs using loop

Hi I'm making SPA react program
I have some question
I want to know how can I use this JSON data HackNews
const [storyIds, setStoryIds] = useState([]);
const list = [];
useEffect(() => {
Top_API().then((res) => {
this.res = res.data.slice(0, 3);
this.res.forEach((ele) => {
axios
.get("https://hacker-news.firebaseio.com/v0/item/" + ele + ".json")
.then((res) => {
list.push({
id: res.data.id,
title: res.data.title,
url: res.data.url,
user: res.data.by,
score: res.data.score
});
setStoryIds(list);
});
});
});
}, []);
this is my code i want to print this api data
I print JSON data like this
{JSON.stringify(storyIds[0])}
This code works well. However, from the storyIds[1] arrangement, it is not visible on the screen. I checked that it was output from the console.
And when I go to a different page,
If I output the contents of my code array, an error occurs that the array cannot be found when you return to the page.
ex)
{JSON.stringify(storyIds[0].title)}
If you write like the code above, an error occurs that the array is not defined.
I've been trying to solve this situation for three days now without a proper solution.
The code that you print on the screen is as follows.
<div className="n1">
<a href={JSON.stringify(storyIds[0])}>
{JSON.stringify(storyIds[0])}
</a>
<br />
by: {JSON.stringify(storyIds[0])}
</div>
<div className="n2">{JSON.stringify(storyIds[1])}</div>
<div className="n3">{JSON.stringify(storyIds[2])}</div>
</div>
the data look's like
[{"id":30186326,"title":"Facebook loses users for the first time","url":"https://www.washingtonpost.com/technology/2022/02/02/facebook-earnings-meta/","user":"prostoalex","score":994},{"id":30186894,"title":"In second largest DeFi hack, Blockchain Bridge loses $320M Ether","url":"https://blockworks.co/in-second-largest-defi-hack-ever-blockchain-bridge-loses-320m-ether/","user":"CharlesW","score":400}]
how can I print this API response my screen?
You need to use async await with Promise.all for waiting for response from API
useEffect(() => {
Top_API().then(async (res) => {
this.res = res.data.slice(0, 5);
Promise.all(
this.res.map(async (r) => {
return await axios.get(
"https://hacker-news.firebaseio.com/v0/item/" + r + ".json"
);
})
).then((resolved) => {
resolved.map((resolve) => {
list.push({
id: resolve.data.id,
title: resolve.data.title,
url: resolve.data.url,
user: resolve.data.by,
score: resolve.data.score
});
});
setStoryIds(list);
});
});
}, []);

Two buttons for one script JS in web

I want to put a button/a for each record and run script for that concrete record but i stuck.
Button/a:
<a class="record-delete" data-doc="<%= shop._id %>">
<img src="/trashcan.svg" alt="delete icon" />
</a>
Script:
const trashcan = document.querySelector('a.record-delete');
trashcan.addEventListener('click', (e) => {
const endpoint = `/shops/${trashcan.dataset.doc}`;
fetch(endpoint, {
method: 'DELETE'})
.then(response => response.json())
.then(data => window.location.href = data.redirect)
.catch(err => console.log(err));
});
Script works only for last record. I know that i can use:
document.querySelectorAll
Instead of:
document.querySelector
But I don't have any idea how to run script for concrete button/a, as it still need concrete variable/target.
Thank you in advance for help if You can ;)
maybe this will help, https://jsfiddle.net/px59m3t2/
const trashcans = [...document.querySelectorAll('a.record-delete')];
trashcans.forEach(trashcan => {
trashcan.addEventListener('click', (e) => {
alert(e.target.parentNode.getAttribute('data-doc'));
});
});

Navigating JSON tree to data from Reddit API

I will try and keep this short. I am a current student and have been attempting to retrieve the top 5 posts from the front page of Reddit and display the title and URL on an HTML page. It is probably something really simple, but I can't get it to work. I want to pass the data to my Handlebars template from a single variable. I keep receiving an unhandled promise warning. Here is my code.
let url = 'https://www.reddit.com/.json?limit=5';
let settings = { method: "Get"};
let redditData = ""
fetch(url, settings)
.then(res => res.json())
.then(data => {
redditData = [
{
title: data.children.data.title,
url: data.children.data.url_overriden_by_dest
}
];
});
The data object is structured differently than they way you've coded it. Here is how to extract the information you want from the first child:
let url = 'https://www.reddit.com/.json?limit=5';
let settings = { method: "Get"};
let redditData = ""
fetch(url, settings)
.then(res => res.json())
.then(data => {
redditData = [
{
title: data.data.children[0].data.title,
url: data.data.children[0].data.url_overriden_by_dest
}
];
});
You might want to check some documentation on how the function fetch works here.
Also, check how promises work here.
That being said, you have to access the object properties, only when the Promise has finished retrieving the data. One way is using the Promise.allSettled function.
Please see the following snippet working, with a slightly different way of organizing it:
const url = "https://www.reddit.com/.json?limit=5";
const promise = fetch(url).then(res => res.json());
function formatHandlebarsData(data) {
const childrenObj = data.value.data.children;
return childrenObj.map(element => ({
title: element.data.title,
url: element.data.url
}));
}
Promise.allSettled([promise]).then(([data]) => {
const handlebarsData = formatHandlebarsData(data);
// You can use the object now
console.log(handlebarsData);
});
Awesome. I was able to get it working with
let url = 'https://www.reddit.com/.json?limit=5';
let settings = { method: "Get"};
let redditData = ""
fetch(url, settings)
.then(res => res.json())
.then(data => {
redditData = [
{
title: data.data.children[0].data.title,
url: data.data.children[0].data.url_overriden_by_dest
}
];
});
Thanks!

Trouble using Fetch to grab a JSON value and output as text in html

I am trying to grab a value from an API and output it into my html code as text. The API link is "https://financialmodelingprep.com/api/v3/company/profile/AAPL" (data is in JSON). The code below is my attempt at getting the price. My end goal is to have the user enter a stock ticker into an input box and the price for the stock to be outputted as text. I have successfully used the document.value function for returning values upon button clicks but I am not able to get it to work using an API and fetch.
Thank you very much!
<!DOCTYPE html>
<html>
<head>
<title>Pareto</title>
<script>
function xStockPrice(); {
const fetch = require("node-fetch");
const apiURL = "https://financialmodelingprep.com/api/v3/company/profile/AAPL"
fetch(apiUrl)
.then((res) =>res.json())
.then(data => console.log(data.profile.price))
document.tickerInputForm.output.value=data.profile.price
}
</script>
</head>
<body>
<form name="tickerInputForm">
<input type="text" name="xTicker"/>
<input type="button" value="Get Quote" onclick="xStockPrice();"/>
<input type="text" name="output"/>
</form>
</body>
</html>
You just have a few minor errors in your code, it should look like this:
function xStockPrice(); {
const fetch = require("node-fetch");
const apiURL = "https://financialmodelingprep.com/api/v3/company/profile/AAPL"
// Before you used apiUrl, JavaScript variables are case sensitive
// so apiURL is not the same as apiUrl and vice versa
fetch(apiURL)
.then((res) => res.json())
.then(data => {
console.log(data.profile.price);
// Before this line lived outside of your then handler
// Which causes two issues:
// 1: data will be undefined, it only exists in the scope of this anonymous function
// 2: The code will execute before your request is finished, you use then to wait for the response, so even if you had created the variable data before, it would be undefined when this line was executed, you use then to fill in the value and then you can use it to set the value of your input element
document.tickerInputForm.output.value = data.profile.price;
})
.catch(error => console.log(error));
}
The error in your code is the semi-colon in your function declaration function xStockPrice();
It should be like this:
function xStockPrice(){
const fetch = require("node-fetch");
const apiURL = "https://financialmodelingprep.com/api/v3/company/profile/AAPL"
fetch(apiURL)
.then((res) => res.json())
.then(data => {
console.log(data.profile.price);
document.tickerInputForm.output.value = data.profile.price;
})
.catch(error => console.log(error));
}
Using the JavaScript fetch your code works fine.
<!DOCTYPE html>
<html>
<head>
<title>Pareto</title>
<script>
function xStockPrice() {
// const fetch = require("node-fetch");
const apiURL =
"https://financialmodelingprep.com/api/v3/company/profile/AAPL";
fetch(apiURL)
.then(res => res.json())
.then(data => {
console.log(data.profile.price);
document.tickerInputForm.output.value = data.profile.price;
})
.catch(error => console.log(error));
}
</script>
</head>
<body>
<form name="tickerInputForm">
<input type="text" name="xTicker" />
<input type="button" value="Get Quote" onclick="xStockPrice();" />
<input type="text" name="output" />
</form>
</body>
</html>

How to save input from text field to name property in a Javascript object literal?

assistant.parsePostParams((params) => {
let message = {
name: "anon",
body: params.body,
when: new Date().toISOString()
}
}
Let me preface a little first...
This was all built in a classroom working with partners as a project for servers and clients. I think part of why the code has a lot of issues is because I've thrown my hands up in frustration at it and have just been writing anything and trying it then either not removing all of it properly or commenting it out also not properly. At one point everything worked, but am now trying to add to it. There was a spec.js we were running tests from using jasmine--node. Anyway thanks again
Also this is my first time posting so please be gentle. This isn't my complete code obviously, but I am wondering how to change the code so that "anon" can be something that is input by the user. Currently, I am using 'body' in the client and getting messages input as I want them to... sort of. But I can't figure out how to input a username and save it as the name. This is the part of the code I thought is most relevant to the issue. I have 2 main files, my client and my server, and 3 objects. So it would be sort of problematic to link everything here. Any help would be appreciated, thank you!
here is the entire index.html. its a work in progress... please dont laugh
<!DOCTYPE html>
<html lang- "en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<meta http-equiv="X-UA-Compatible" content="ie-edge">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Chat</h1>
<div class="pickRoomDiv">
<button id="pickRoom">Enter Room</button>
<select>
<option title="selectRoom">Select Room</option>
<option title="chatRoom">chat room</option>
</select>
</div>
<div id="form-input">
<form id="name-form" action="/" method="POST">
<input type="text" placeholder="Enter Username">
<input type="submit" name="body" value="Submit Username">
</form>
</div>
<div id="form-input" class="submitDiv">
<form id="chat-form" id="newMessageInput" action="chat" method="POST">
<input type="text" name="body" placeholder="Enter Message">
<input type="submit" value="Submit Message">
</form>
<button id='getAllNow' action='chat' method='GET'>Get All Messages</button>
<!-- <form id="getMessages" action="chat" method="GET"></form> -->
</div>
<div id='chat-log'></div>
<script>
let chatForm = document.getElementById('chat-form')
let chatLog = document.getElementById('chat-log')
let getMessages = document.getElementById('getAllNow')
let submitName = document.getElementById('name-form')
let since
let messages = []
chatForm.addEventListener('submit', (event) => {
// prevents the event from performing the default function.
event.preventDefault();
let inputElement = chatForm.querySelector('input[name=body]')
// let inputElement = document.getElementById('newMessageInput')
let message = inputElement.value
// the function below gets all of the parameters from the URL so I can use them later.
let params = new URLSearchParams();
params.append('body', message)
fetch('/chat', {
method: 'POST',
body: params,
})
.then((response) => response.json())
.then((messages) => {
chatLog.innerHTML = messages.map(message => message.body).join('<br>')
})
})
getMessages.addEventListener('click', (event) => {
fetch('/chat', {
method: 'GET',
})
.then((response) => response.json())
.then((messages) => {
let latestFormatChatMessages = messages.map((message) => {
let newPTag = (`<p class="fancy"> <strong>${message.body}</strong></p> <p class="when">${message.when}</p> <p class="fancy"><strong>${message.name}</strong> </p>`)
return newPTag
})
chatLog.innerHTML = latestFormatChatMessages.join('<br>')
submitName.value
})
})
I am getting name back as undefined. here is the server code.
const http = require('http');
const mime = require('mime-types');
const Assistant = require('./assistant');
const House = require('./lib/house');
const port = process.env.PORT || 5000;
let messages = [];
let house = new House();
http.createServer(handleRequest).listen(port);
console.log("Listening on port " + port);
function handleRequest(request, response) {
let assistant = new Assistant(request, response);
let path = assistant.path;
let [_, base, roomId] = path.split('/')[1]
if (roomId = "") {
roomId === 'general'
}
roomId = roomId || 'general'
function sendMessages(messages) {
let data = JSON.stringify(messages);
let type = mime.lookup('json');
assistant.finishResponse(type, data);
}
// function submitName(messages) {
// let data = JSON.stringify(messages);
// let type = mime.lookup('json');
// assistant.finishResponse(type, data)
// }
try {
let data = JSON.stringify(messages);
let type = mime.lookup('json');
if (path === '/') {
assistant.sendFile('index.html');
} else if (path === '/chat') {
console.log(request.method)
if (request.method === 'GET') {
let room = house.roomWithId(roomId)
let messages = room.messagesSince(0)
sendMessages(messages)
} else {
console.log('Parsing the POST');
assistant.parsePostParams((params) => {
let message = {
body: params.body,
when: new Date().toISOString()
}
messages.push(message);
assistant.finishResponse(type, data);
console.log(type)
house.sendMessageToRoom(roomId, message);
})
}
} else {
let fileName = path.slice(1);
assistant.sendFile(fileName)
}
} catch (error) {
assistant.sendError(404, "Error: " + error.toString());
}
}
// function handleRequest(request, response0 {
// let url = require('url')
// })
// console.log('Parsing the GET')
// let data = JSON.stringify(messages);
// let type = mime.lookup('json');
// assistant.finishResponse(type, data);
There are a lot of issues with your code. Looking at your code it seems like you do not have clear idea of how server-client architecture works. It seems like you are trying to make a chat application. You need to take care of three things here.
Client: Takes name of chatroom, username and message. Then on press of a button sends the data to server by making a POST request and waits for response.
Server: Receives the data sent by client and saves it in a database. If save is successful, server sends back a success response. This response may also include the saved row in database. If save is unsuccessful, and error message should be returned.
Client: Receives the response. If the response is success, then updates the chat list. If response is an error, communicate the error message to user.
I fixed the client a little bit so that you get the required information and send it to server.
Client
const sendMessage = document.getElementById('send-message');
const username = document.getElementById('username');
const message = document.getElementById('message');
const chatLog = document.getElementById('chat-log');
const getMessages = document.getElementById('get-all-messages');
const messages = [];
sendMessage.addEventListener('click', (e) => {
const d = new Date().toISOString();
alert("Username: " + username.value + '\n' +
"Message: " + message.value + '\n' +
"When: " + d);
// the function below gets all of the parameters from the URL so I can use them later.
fetch('/chat', {
method: 'POST',
body: {
body: message.value,
name: username.value,
when: d,
},
})
.then((response) => response.json())
.then((messages) => {
chatLog.innerHTML = messages.map(message => message.body).join('<br>')
});
});
getMessages.addEventListener('click', (e) => {
fetch('/chat', {
method: 'GET',
})
.then((response) => response.json())
.then((messages) => {
let latestFormatChatMessages = messages.map((message) => {
return `<p class="fancy"><strong>${message.body}</strong></p> <p class="when">${new Date(message.when)}</p><p class="fancy"><strong>${message.name}</strong> </p>`;
})
chatLog.innerHTML = latestFormatChatMessages.join('<br>');
});
});
<!DOCTYPE html>
<html lang- "en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<meta http-equiv="X-UA-Compatible" content="ie-edge">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Chat</h1>
<div class="pickRoomDiv">
<button id="pickRoom">Enter Room</button>
<select>
<option title="selectRoom">Select Room</option>
<option title="chatRoom">chat room</option>
</select>
</div>
<div id="form-input">
<input id="username" type="text" placeholder="Enter Username">
<input id="message" type="text" placeholder="Enter Message">
<button id="send-message">
SEND
</button>
</div>
<br>
<br>
<button id='get-all-messages'>Get All Messages</button>
<div id='chat-log'></div>
</body>
</html>
I would suggest that you start off by following a tutorial that teaches you key concepts. There is an option to use sockets. Sockets help in real-time messaging.
Following medium tutorial should help you understand the concepts of programming and code formatting.
Chat app tutorial

Categories

Resources