How to access data inside Json nested objects from an API - javascript

I am using cryptocomare API to get crypto coins data within a Nextjs App. What i doing is that when a user clicks on a perticular symbol, i redirect it to the coin details page where i try to extract the clicked symbol with getServerSideProps as follows and then dynamically put in the API call and send it to the API server.
`
export const getServerSideProps = async (context) => {
const res = await fetch(
`https://min-api.cryptocompare.com/data/pricemultifull?tsyms=USD&fsyms=${context.params.symbol}`
);
const icon = await res.json();
return {
props: {
icon,
},
};
};
`
This call returns a json object of nested objects and it goes to 2-3 levels deep. On Top it looks like following:
API call response
Inside my code, I want to access the data Object -> RAW -> (whatever the user clicked on). But, Since the Symbol or coin queried by the user is dynamic (means i can't predict what is clicked) I never know what to query. SO i tried this to access the data object.RAW[0]
In principal it should give me the whatever object is inside the object.RAW But it returns undefined
Can please someone guide me , how can i get the data inside object.RAW without knowing what is inside?
Thanks!
I have tried object.RAW[0] to access the data...,....

You can use Object.values(object.RAW) to get an array of the values inside RAW (assuming RAW is not undefined)
Doc: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

Related

How to display all players names in the Ball Don't Lie API array

I am doing one of my first projects using the Ball Don't lie API, trying to build my version of an ESPN landing page. I am using https://www.balldontlie.io/api/v1/players. I am using Javascript, I have been stuck for days trying to understand how to display the first and last name of all of the players on the landing page in HTML. I only know how to display one name if I use data.data[0]. I've tried .map, loops, it's just not clicking. I want to be able to display other stats in the array as well. Can anyone help?
This my Javascript code:
async function getPlayers() {
const response = await fetch ('https://www.balldontlie.io/api/v1/players');
const data = await response.json();
const players = data.data;
console.log(players);
displayPlayer(players);
}
function displayPlayer(players) {
const scores = document.getElementById('scores');
scores.innerHTML = `
${players.first_name} ${players.last_name}`;
}
getPlayers()```
I had tried .map, I've tried loops, I am just not understanding what function is going to show the players. Maybe my orignal code doesn't make sense. I've tried watching Youtube and can't find anyone doing it in simple Javascript.
You can try this in your script and edit points 2. and 4. for better display of what you need to show
// 1. GET request using fetch()
fetch("https://www.balldontlie.io/api/v1/players")
// Converting received data to JSON
.then((response) => response.json())
.then((json) => {
// 2. Create a variable to store HTML table headers
let li = `<tr><th>ID</th><th>first_name</th><th>height_feet</th><th>height_inches</th> <th>last_name</th><th>position</th><th>im lazy...</th></tr>`;
// 3. Loop through each data and add a table row
console-console.log(json.data);
json.data.forEach((user) => {
li += `<tr>
<td>${user.id}</td>
<td>${user.first_name} </td>
<td>${user.height_feet}</td>
<td>${user.height_inches}</td>
<td>${user.last_name}</td>
<td>${user.position}</td>
<td>${user.team.id}</td>
<td>${user.team.abbreviation}</td>
<td>${user.team.city}</td>
<td>${user.team.conference}</td>
<td>${user.team.division}</td>
<td>${user.team.full_name}</td>
<td>${user.team.name}</td>
</tr>`;
});
// 4. DOM Display result
document.getElementById("users").innerHTML = li;
});
And your html body part look like this
<div>
<!-- Table to display fetched user data -->
<table id="users"></table>
</div>
Your constant players is an array. In order to access a player's information within that array, you would need to index each player to then access their object of key:value pairs.
That is why you can get the first player's name to show when you save players as data.data[0]. This is indicating that you want to access the object in position 0 in the array. If you wanted the second player's information you would reference data.data[1], and so forth.
With trying to keep as much of your original code as possible (and adding some comments), I believe this is what you were trying to achieve.
async function getPlayers() {
// Fetch the API and convert it to json.
const response = await fetch ('https://www.balldontlie.io/api/v1/players');
const data = await response.json();
// Save the returned data as an array.
const players = data.data;
console.log(players);
// Create an element to display each individual player's information.
players.array.forEach(player => {
displayPlayer(player);
});
}
function displayPlayer(player) {
// Grab the element encasing all players.
const scores = document.getElementById('scores');
// Create a new element for the individual player.
const playerContent = document.createElement('div');
// Add the player's name.
playerContent.innerHTML = `
${player.first_name} ${player.last_name}`;
// Add the player content into the encasing division.
scores.appendChild(playerContent);
}
getPlayers()
We will use the forEach() function to index each player's object in the array of data for us, grab your "scores" element you created on your HTML page, then we will "append" (add to the end) each player's information into your "scores" element.
The website link below has some useful information to read that can help you build on your existing code when you want to start adding styling.
https://www.thesitewizard.com/javascripts/insert-div-block-javascript.shtml
This site has some useful information on using "promises" when dealing with async functions that will come in handy as you progress in coding.
https://www.geeksforgeeks.org/why-we-use-then-method-in-javascript/
These website links were added as of 02/04/2023 (just to add as a disclaimer to the links because who knows what they will do in 2030 O.o).
Hope this helps!

Can't save API response to the window object

I have two pages and when use clicks continue on page1, I am calling an API and browser opens page2.
Meanwhile async process is happening and I am trying to save results of API response in the window object. After that I am trying to get access to those values on window object, which are undefined.
What am I doing wrong in my async function?
const {input} = this.state;
this.props.history.push('/step2');
generateBook(payload)
.then(res => {
input.id= res.data.bookId;
input.color= res.data.color;
window.input = input;
})
On page2 I am trying to get access to the window.input.id ad window.input.color
Plese use the following way to pass data to step2
this.props.router.push({
pathname: '/step2',
state: {
inputData:input
}
})
you can retrive it via this.props.location.state in step2 route

Best way to return full object made from data from different APIs

Im working on an app that mainly is a large form that contains several dropdowns. These dropdowns should
populate with some data from the DB. The app has a server with Express that it works as a proxy: I call it from the front end
and then that server calls some external API's, format the info and then send them back to the front.
Im thinking on having on the Backend a route like "/dropdown" call that route from the front end. And once I get the data (I would like to receive it like this)
data: {
dataForDropdown1:[data],
dataForDropdown2:[data],
dataForDropdown3:[data],
dataForDropdown4:[data],
...etc
}
store it on Redux and call them with a selector and populate all the dropdowns required.
The problem is on the server. I need to get that info from different APIs so in the route in Express I was thinking on use something like
Promise.all([promisefetchUrl1],[promisefetchUrl2],[promisefetchUrl3],...etc)
but I don't know how to format like the object above, because as I understand Promise.all doesn't have an order it just returns the info with the first promise resolved, then the second, etc so it would be hard to know
which info is which.
I was thinking on using async await but its way too dirty, like this:
const info1 = await fetch(url1)
const info2 = await fetch(url2)
const info3 = await fetch(url3)
const info4 = await fetch(url4)
etc
then return it like this
const data = {
dataForDropdown1:info1.data,
dataForDropdown2:info2.data,
dataForDropdown3:info3.data,
dataForDropdown4:info4.data
...etc
}
any advices?
Promise.all doesn't have an order it just returns the info with the first promise resolved, then the second, etc so it would be hard to know which info is which.
It does have an order - the first element in the resolve array will correspond to the first Promise in the array passed to Promise.all, etc, regardless of the order in which the promises resolve.
Use:
const results = await Promise.all([
getData(promisefetchUrl1),
getData(promisefetchUrl2),
getData(promisefetchUrl3),
getData(promisefetchUrl4), // this could be made less repetitive
]);
const data = {
dataForDropdown1: results[0],
dataForDropdown2: results[1],
dataForDropdown3: results[2],
dataForDropdown4: results[3],
};
where getData takes the URL and returns a Promise that resolves to the data corresponding to the URL.

Saving a field from firestore that is an array

I am currently working on a mobile app on React and I am having trouble understanding how to save a field from fire store that is an array.
Since I can't post images my database structure is all strings such as username, first name, etc but I have a field called follow list that is an array.
What I want to do is save the usernames from the following list into an array to later search fire store for the username's in the array, this is basically what I want to do so I can render my app's social Feed. I do know that I can probably create another subcollection and write something familiar to what I did to search for users but that was a QuerySnapShot which was overall documents not a specific one and I also know firebase creates an ID for arrays and it increases as the array gets bigger.
I do not want to end up making two more subcollections one for followers and following which I think not ideal right? My current approach is this
export const fetchUserFollowing = async (username) => {
const ref = firebase.firestore().collection('users').doc(username)
let results = []
ref
.get()
.then( doc => {
let data = doc.data()
results = data
})
.catch((err) => {
return 'an error has occurred ', err
})
}
From what I understand is that a DocumentSnapShot .get() function returns an object but what I want is to store follow list into results and then return that but I am not sure how to manipulate the object return to just give me follow List which is an array
https://rnfirebase.io/docs/v5.x.x/firestore/reference/DocumentSnapshot
link to docs

React + Firebase saving issue. Why this Hash?

Im saving my data to database, using React, like this:
export const matchesInitialCreate = (user, matches) => {
return (dispatch) => {
firebaseApp.database().ref(`/users/${user}/matches`)
.push(matches)
.then(() => {
dispatch({ type: MATCHES_INITIAL_CREATE });
});
};
};
My matches entity is a simple json with some data, divided into
matches:{ groups: {...}, knockout {...}}}
Everything looks fine, but when I push it to firebase, it is saved with a hash. Like this:
users/user/matches/CRAZY_HASH/matches/groups
But I want that it saves like this:
users/user/matches/groups
What Im doing wrong?
There are different ways to save data to Firebase Realtime Database.
Push: generates a unique key at the specified reference, and writes the given data under this new child
Set: save data to a specified reference, replacing any existing data at that path
Update: updates lower-level child values of a specified reference
The reason why you see a crazy hash is you are using the push method. If you want to set the data directly under users/{user}/matches/groups, you must use either set or update.
// Will override everything
firebaseApp.database().ref(`/users/${user}/matches`).set(matches)
// Will update specific children
firebaseApp.database().ref(`/users/${user}/matches`).update(matches)

Categories

Resources