Stuck with JSON API Call in Javascript - javascript

I am trying to build a Calculator where you can Pick different Cryptocurrencies and build a Portfolio for Testing and Tracking. I choose Coingecko API v3 for this and use Fetch to do the API Calls. https://www.coingecko.com/en/api
The API Calls are working and I get JSON Data from the Server. I built a Function that is delivering the Top 100 Coins, putting them into a Datalist-Tag for Choosing from an Input:
function fetch_coinlist(url) {
fetch(url)
.then(function(response) {
if (response.status !== 200) {
alert("Can Not get Price Api! Status: " + response.status);
return;
}
response.json().then(function(data) {
document.getElementById("coinlist").innerHTML = "";
for (i = 0; i <= 99; i++) {
const toplist = document.createElement("option");
toplist.id = data[i].symbol;
toplist.innerHTML =
data[i].symbol.toUpperCase() + " - " + data[i].name;
document.getElementById("coinlisting").appendChild(toplist);
//console.log(data[i].id);
//console.log(data[i].name);
//console.log(data[i].symbol);
//console.log(data[i].image);
//console.log(data[i].current_price);
}
});
})
.catch(function(err) {
alert("Can Not get Price Api! Status: " + err);
});
}
<input list="coinlisting" id="coinlist" name="coinlist" class="curser-choose" />
<datalist id="coinlisting" placeholder="Choose Coin"></datalist>
This is working, I am using a For loop to go through the response. I try to Display the Price for a Coin if the User picked one Option from this Datalist and for further functionality I think it would be best that I could call an object like data.coinname.current_price so I can build a Function where i could pass a string to it and get the price for that coin.
However, right now I would have to use data[0].current_price for the current Price of the first item in the list. The items on the called List can Change over time, so I can not make a static assignment, I think I could do this each time I call the API but it would not benefit my target to have a function that I can feed with a name as a string to do the Price Call.
It is possible to get the Price in the same call as the list but I can not figure out how I would be able to do what I have in mind with that. On the site for the API are different calls listed, one of the first is the /coins/list call and it says "Use this to obtain all the coins’ id in order to make API calls" and gives a JSON object for each available coin like:
{
"id": "1inch",
"symbol": "1inch",
"name": "1inch"
}
Do I need to do this call first in order to achieve what I have in mind? But I'm unsure how that would help me get the solution I am looking for... I am struggling to find a solution for this and feel stuck, I feel like I don't understand it properly and it should be not as hard as I think it is right now :D If you have an idea of how to accomplish this please let me know!

You could do something like this. I kept the html simple.
fetch_coinlist: fetches a coin list. After fetching the coins list it converts the result to an object instead of a list. Each coin can be accessed using coins["<coin id>"].
show_coinlist does the visualisation
addEventListener catches when you select an item.
const gecko = "https://api.coingecko.com/api/v3/";
var coins = {};
// selector actions
const selector = document.querySelector('#coinlisting');
const info = document.querySelector('#info');
selector.addEventListener('change', event => {
info.innerHTML = "Selected item: " + selector.value + " : " + coins[selector.value].name;
});
function fetch_coinlist() {
fetch(gecko + "coins/list")
.then(function(response) {
if (response.status !== 200) {
alert("Can Not get List Api! Status: " + response.status);
return;
}
response.json().then(function(data) {
coins = {};
for (let i = 0, l = data.length; i < l; i++) {
let {id, ...info} = data[i];
coins[id] = info;
}
show_coinlist();
});
})
.catch(function(err) {
alert("Can Not get Price Api! Status: " + err);
});
}
function show_coinlist(){
for (let id in coins) {
let item = coins[id];
const toplist = document.createElement("option");
toplist.value = id;
toplist.innerHTML = item.symbol.toUpperCase() + " - " + item.name;
document.getElementById("coinlisting").appendChild(toplist);
}
}
fetch_coinlist();
<select id="coinlisting" placeholder="Choose Coin"></select>
<div id="info"></div>

Related

How to get groups a given user is a part of in SharePoint?

I'm trying to get the groups a given user (typed into a textbox in page) is a member of. Haven't had much success so decided to get all the groups, iterate through their users to find the groups the user is a part of. Tried the following but can't find a way to iterate through the users.
what am I missing? is there a better way to achieve my main goal?
var oGroupCollection, clientContext, loadedGroup, oUserCollection, oUser ;
function GetAllSiteGroups() {
// You can optionally specify the Site URL here to get the context
// If you don't specify the URL, the method will get the context of the current site
var clientContext = new SP.ClientContext("http://MyServer/sites/SiteCollection");
// Get Site Group Collection object
oGroupCollection = clientContext.get_web().get_siteGroups();
//oUserCollection = oGroupCollection.getByTitle('sp_red_dehn_zigaretten').get_users();
//console.log(oUserCollection);
// Load Site groups
clientContext.load(oGroupCollection);
// Execute the query to the server.
clientContext.executeQueryAsync(onsuccess, onfailed);
}
function onsuccess() {
// Iterate through each item
var oEnumerator = oGroupCollection.getEnumerator();
while (oEnumerator.moveNext()) {
var oGroup = oEnumerator.get_current();
console.log(oGroup);
console.log("Title of the group is: " + oGroup.get_title() + "\n");
oUserCollection = oGroup.get_users();
console.log(oUserCollection);
clientContext.load(oUserCollection);
clientContext.executeQueryAsync(onsuccess2, onfailed);
}
}
function onfailed(sender, args) {
console.log('Failed' + args.get_message() + '\n' + args.get_stackTrace());
}
function onsuccess2() {
// Iterate through each item
var oEnumerator = oUserCollection.getEnumerator();
while (oEnumerator.moveNext()) {
oUser = oEnumerator.get_current();
console.log(oUser);
//console.log("Title of the group is: " + oUser.get_title() + "\n");
}
}

Trying to limit my results and sort my data, from MongoDB using NodeJS

I am using MongoDB and Node.JS, I am trying to get data out of my MongoDB and show into my html page which I have working with the below code however this just brings back ALL entries in no particular order:
server.js
// This is for getting the list of all players from my DB
app.get("/getPlayers", function(request, response) {
db.getPlayers().then(function(players){
console.log(players);
response.send(players);
});
});
leadership.html
<script>
$(function() {
$.get("http://localhost:9000/getPlayers", {}, function (res) {
let data = res;
console.log(res);
for (i = 0; i < data.length; i++) {
let name = data[i].name;
let score = data[i].score;
console.log(data[i].name);
$("#leadership").append("<tr><td class=\"name\">"
+ data[i].name + "</td><td class=\"score\">"
+ data[i].score + "</td></tr>");
}
});
});
</script>
After looking at W3 Schools I tried to alter the code to this:
db.getPlayers().sort().limit(10).then(function(players)
However my Chrome console brings back an internal server error 500. Can someone point out how I can sort by LARGEST NUMBER first, then LIMIT the results to say 10? Within the database there is a collection called players, which holds name and score
db.js
var Player = mongoose.model("Player", {name: String, score: Number});
module.exports.Player = Player;
Try something like this.
Order, sort and limit can be passed from front end or change default values after : mark.
Players is imported model, you can do it this way or use method in the model itself.
app.post('/api/players',(req,res)=>{
let order = req.body.order ? req.body.order : "-1";
let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
let limit = req.body.limit ? parseInt(req.body.limit) : 100;
Players.
find().
sort([[sortBy,order]]).
limit(limit).
exec((err,players)=>{
if(err) return res.status(400).send(err);
res.status(200).json({
size: players.length,
players
})
})
})

Firebase - Toggling value with transactions

I'm trying to let users favorite a project. I'm storing these projects at 2 places so I have to update them simultaneously. After looking at the firebase docs, using transactions seemed to be the best option.
.
Function to toggle the favorite status:
function toggleFavorite (projectReference, uid) {
projectReference.transaction(function(project) {
console.log('Before-Favorites :' + project.favoriteCount);
if (project.favorites && project.favorites[uid]) {
project.favoriteCount--;
project.favorites[uid] = null;
} else {
project.favoriteCount++;
if(!project.favorites) {
project.favorites= {};
}
project.favorites[uid] = true;
}
console.log(' After-Favorites :' + project.favoriteCount);
return project;
});
};
Function to add the eventListeners to the projects:
function AddToFavorite (uid, authorId) {
const favoriteList = document.querySelectorAll('.btnFavorite');
for(var i = 0; i<favoriteList.length; i++) {
favoriteList[i].addEventListener('click', function(event) {
const projectId = this.dataset.id;
console.log(projectId);
const globalProjectRef = firebase.database().ref('/projects/' + projectId);
const userProjectRef = firebase.database().ref('/user-projects/' + authorId + '/' + projectId);
toggleFavorite(globalProjectRef,uid);
toggleFavorite(userProjectRef,uid);
});
}
}
I want to store the uid of the current user under a 'favorites' node within the project location.
When i want to store the data I can see it appearing in the database but removing it after instantly. Followed by that i get an error in the console that my project object is null.
What's the best way of solving this issue ?

Getting data from Swapi API https://swapi.co/api/people/

I want to fetch the https://swapi.co/api/people/ all name and other detail but when I am using an axios call to get the data and I am getting undefined for all data but if want one name I am getting a CORS error in console.
let button = document.querySelector("#button");
let name = document.querySelector("#displayDetail");
function getDetail(){
var apiURL="https://swapi.co/api/people";
axios.get(apiURL).then(function(response){
showDetail(response.data);
});
}
function showDetail(data){
name.innerText=data.name;
}
button.addEventListener('click',getDetail);
The JSON data from https://swapi.co/api/people doesn’t have a name member. Instead it has a results member that is an array of objects, each of which has a name member.
So you need to loop through that data.results array to get each name:
function getDetail() {
var apiURL = "https://swapi.co/api/people";
axios.get(apiURL).then(function(response) {
showDetail(response.data);
});
}
function showDetail(data) {
for (i = 0; i < data.results.length; i++) {
console.log(data.results[i].name);
}
}
getDetail();
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
But note: That API endpoint paginates the results; so to get all the names, check data.next to get the URL for the next page, then make a new request with that URL to get the next set of results:
function getDetail(apiURL) {
axios.get(apiURL).then(function(response) {
showDetail(response.data);
});
}
function showDetail(data) {
for (i = 0; i < data.results.length; i++) {
names = names + data.results[i].name + "\n";
// name1.innerText = name1.innerText + "\n" + data.results[i].name;
}
if (data.next) {
getDetail(data.next);
} else {
console.log(names); // name1.innerText = names;
}
}
var names = "";
getDetail("https://swapi.co/api/people");
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
try with this
swapi.co/api/people/
change for
swapi.dev/api/people/
All resources support a search parameter that filters the set of resources returned. This allows you to make queries like:
https://swapi.co/api/people/?search=r2d2
To see the set of search fields for each resource, check out the individual resource documentation.

Parse query (callback) in for loop

New to javascript here, so callbacks are still a little iffy in my brain.
What I'm trying to do is: given a "menu" which is an array of objectId's, query for each foodItem that corresponds to that objectId, get its votes, put it in a min-heap (to determine which are the top 5 items), and return those top 5 items.
My heap at the end is empty because I realize that JavaScript is asynchronous and that when I try to get the heap data, the callback might not have necessarily completed.
If it were just one call, I would just nest the callbacks, but since this is a loop I'm not really sure what to do.
function getTopFoods(menu, heap, callback) {
//go through each objectId, get its foodItem and then its votes, then heap it
console.log("got to TopFoods");
for (var i = 0; i < menu.length; i++) {
var foodID = menu[i];
var FoodItem = Parse.Object.extend("FoodItem");
var foodQuery = new Parse.Query(FoodItem);
foodQuery.equalTo("objectId", foodID);
//get corresponding foodItem
foodQuery.find({
success: function(foodResult) {
//got specific food Item
var votes = foodResult.get("votes");
console.log("votes: " + votes);
if (heap.length < 5) {
heap.queue(foodResult);
} else {
if (votes > heap.peek().get("votes")) {
heap.dequeue();
heap.queue(foodResult);
}
}
},
error: function(error) {
console.log("Food error: " + error.code + " " + error.message);
}
});
}
var topFoods = [];
for (var i = 0; i < 5; i++) {
topFoods[i] = heap.dequeue();
}
callback(topFoods);
}
The easiest way is to use promises; at this stage, this involves using a library (coming to JavaScript proper in ES6). If you want a low-tech solution, just count stuff:
var waitingCount = menu.length;
for (....) {
...
success: function(foodResult) {
...
if (!--waitingCount) {
callback(topFive(heap));
}
},
error: function(error) {
--waitingCount;
...
}
...
}
This is just the basic idea. It would be good if you also decremented the counter on failed responses, since this way a single fail will leave you hanging.
EDIT: Err, obviously, the check needs to go to the bottom of success, not to the top as my snippet indicated before, or you'll miss the last element. I also put in the error case.
EDIT2: As eth3lbert notes, parse.com API also supports promises (I don't work with parse.com, so... thanks for the tip). In that case, here's what you do:
var promises = [];
for (....) {
var promise = foodQuery.find({
...
});
promises.push(promise);
});
Parse.Promise.when(promises).then(function()) {
callback(topFive(heap));
}

Categories

Resources