Getting response data out of Fetch blob from Wikipedia api - javascript

I'm trying to use Wikipedia's api with fetch.
const endpoint = 'https://en.wikipedia.org/w/api.php?
action=query&format=json&origin=*&titles=Albert%20Einstein'
fetch(endpoint)
.then(blob => blob.json())
.then(data => console.log(data))
RETURNS
I'm not sure how to drill down in this, due to that 736. I assume there is nothing there? What do these results mean?
I did these loops to see if they allowed me something I could not get by clicking in the console. It's the same as fetch call above so not really useful. Just wanted to show that I tried something at least (downvote control).
fetch(endpoint)
.then(blob => blob.json())
.then((data) => {
for(var i in data){
//returns batch complete ,
//& query
for(var j in data.query){
//returns pages
for(var k in data.query.pages){
//returns the string 736
}
}
}
})
Does nothing more than clicking the console results above.

Use formatversion=2 for a slightly more comfortable format (where data.query.pages is an array).
Alternatively, you could iterate the object with something like
var pages = data.query.pages;
for (pageId in pages) {
if (pages.hasOwnProperty(pageId)) {
console.log(pages[pageId]);
}
}
In modern browsers you can also use Object.values() to get the properties of the object in an array.

Related

How to fetch data properly for this API? (array)

console.log screenshot
Hi, I am using "fetch" method with API for my website, and this API shows book information, if books include the input title.
Screenshot attached is console.log result when typing an example book title.
I'd like to get every title info of each array, could anyone can help me on this?
Especially I am not sure what is the proper line for this.
.then((data) => {document.getElementById("bookinfo").innerHTML=
data['documents'.authors];
Entire script for fetch is below.
<script>
function getBook(){
let bookvalue=document.getElementById("book").value;
fetch('https://dapi.kakao.com/v3/search/book?target=title&query=' + bookvalue, {
headers: {
Authorization: "KakaoAK TokenID"
}
})
.then((response) => response.json())
.then((data) => {document.getElementById("bookinfo").innerHTML=
data['documents'.authors];
});
}
</script>
You're not calling the array index correctly, data['documents'.authors] should be data.documents[0].authors to get the author of the first item and data.documents[1].authors to get the second, etc...
What do you intend to do with the titles?
EDIT: Fixed it for easier use (I think this is what you want)
.then(data => data.documents.map(book => book.title)).then(titles => document.getElementById("bookinfo").innerHTML = titles.join(", "));
Otherwise create an array
const titles = [];
push into array
.then(data => data.documents.map(book => titles.push(book.title))
But you might have issues with this and get empty array since the promise might still be pending

Using data pulled from an API

It's been half a day now of trying to figure this out, and while some progress has been made, and a ton of useful research, I'm still a newbie so I need help.
What I need is to use the data that I'm pulling from an API to use as a JS variable. My API is giving me the following output:
{"bitcoin":{"usd":9695.66,"usd_24h_change":2.0385849528977977}}
I want to use the usd and usd_24_change values from that string, maybe as some JS variable for further calculations.
So far what I've managed to do was to push the string directly in HTML, so I can have a visual representation of it, however I need to pull the values from it in the backend (hope that makes sense?)
My code so far:
fetch(url)
.then(response => response.text())
.then(data => {
$('#apiPlaceholder').html(data);
});
I've honestly ran out of ideas. My only alternative would be trying to pull the values directly from the HTML string but I feel like that would be a really clunky way of doing it. I'm sure there's ways to interpret the data in the backend.
Any ideas would definitely be appreciated! :)
Here's how you would go about doing that:
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data["bitcoin"]["usd"]);
console.log(data["bitcoin"]["usd_24h_change"]);
});
you need to parse the response and then just save it.
fetch(url)
.then(response => response.text())
.then(data => {
const parsedData = JSON.parse(data);
const usd = parsedData.bitcoin.usd;
const usd_24h_change = parsedData.bitcoin.usd_24h_change;
});
or display it instead;

How to use array items as parameter for API call

I am currently trying to log out the names and ID of a various items for a video game using an array which holds the ID of each item.
Currently I have the following.
const URL =
"http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json?item=";
const items = ["4151", "2"];
items.map(item => {
fetch(`${URL}${item}`)
.then(data => data.json())
.then(({ item: { id, name } }) => console.log(`${id}: + ${name}`));
});
I should be getting 4151: Abyssal Whip as a format for each item, but it isnt working. I have done this in the past using a cryptocurrency api, but I cant get it to work here, and I am not sure where I am going wrong.
Thanks for the help in advance.
Some more detail would help. If you open dev tools and look at console output when hitting the API, you might be getting an error... maybe a Mixed-Content error? The runescape API is returning from an HTTP connection. If you are requesting from an HTTPS connection, it will not allow the resource to be delivered. Otherwise, your code should run (but the +) won't be necessary because you're using template literals.
I am sure its a typical CORS policy error. Here's how I managed to fetch the data. The heroku API enables cross-origin requests to anywhere.
const items = ["4151", "2"];
const proxyUrl = "https://cors-anywhere.herokuapp.com/",
targetUrl =
"http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json?item=";
items.map((item) => {
fetch(proxyUrl + targetUrl + item)
.then((data) => data.json())
.then(({ item: { id, name } }) => console.log(`${id}: + ${name}`));
});

NodeJS + MySql nested queries

I'm trying to get users from database and then loop throug each user and get their images. However when I try to assign images array to user.images property nothing happens. I still get only users with empty images array.
Currently my code is the following:
user.getAll().then(result =>{
const userCollection = result[0];
for(let i=0; i < userCollection.length; i++){
userCollection[i].images = [{}];
image.getImagesByUserId(userCollection[i].Id).then(res =>{
userCollection[i].images = res[0];
}).catch(err =>{
console.log(err);
res.status(400).json(err);
})
}
res.json(userCollection);
})
.catch(err =>{
console.log(err);
res.status(400).json(err);
});
Why I can't assign images array to it's property?
It looks to me like you need to run your res.json(userCollection) from inside the callback.
This will of course mean you need to rename your res variable in the callback
This is assuming you are somehow using res.json(userCollection) to export the information. Which I am inferring based on the fact I don’t see res defined anywhere
May be a silly question, but are you assigning it? I only see
userCollection[i].images = [{}];
above and never see:
userCollection[i].images = res;
assignment once you grab the images.
The problem is that getImagesByUserId() is asynchronous so by the time you get to the assignment, you've already sent the response.
The order of events you have currently is:
Assign an empty image list to all the users
Queue up a load of database requests
Send the response (res.json())
Reassign the images for all the users once the database results come back.
The easy fix is to look at Promise.all() and aggregate the results when they all come back.
However, this isn't the most efficient way to deal with SQL databases, I would suggest you restructure your query so that you get all the images for all the users in 1 trip to the database and then format the response based on those results.
Say you have an image table and a user table, something like:
SELECT image_name, user_id
FROM image
then replace your loop in your js with:
getImagesForUsers().then(result => {
//create your response from the rows
res.json(response);
});

How to limit the amount of data returned from a JSON file using fetch?

I have this fetch statement that returns 19 building names, but I only want 10; the following is what I attempted, but I still get 19 building names.
fetchBuildings(energyProgramId) {
fetch(`http://localhost:1001/api/energyprograms/${energyProgramId}/buildings/?results=10`)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
buildings: json,
})
});
}
Is there something extra I need to add?
Here is an example:
1.fetch('http://jsonplaceholder.typicode.com/posts/')
The above URL gives array of objects with 100 elements because it originally is an array of 100 elements.
2.fetch('http://jsonplaceholder.typicode.com/posts/?_limit=10')
This URL gives array of objects with 10 elements.
Notice the difference?
I only did this : ?_limit=10 ----> Add any number in place of 10 and hopefully you will get desired results.
As the other answer already points out the best/most normal solution would be to change on the backend how the API returns data. Typically REST API's support query parameters such as limit and start or page and resultsPerPage.
If this is not available - e.g. when you're fetching an external resource - an alternative which is often supported by static file servers and sometimes by API's is the Range header which allows you to retrieve only a specific byte range of the resource (do note, in the case that an API supports this it will still load the entire resource on the server, but it will not transmit the entire resource). An example with fetch would look like
fetch('', { headers: { range: 'bytes=0-1000'} })
When doing this on XML or JSON resources it can be somewhat difficult to work with, but with for example CSV files it's ideal.
No different from fetch to XHR or axios or anything else. actually, no different from react or angular or vue or anything else.
This is an API that backend developers wrote it and it is based on REST API, so when you call it as GET or POST and anything else you just fetch the JSON that the backend developers designed it. BUT
There is a new technology that name is GraphQL. you can call API and then you just fetch the JSON what you want. Also, it must be implemented in backend but it is possible.
It's not closely bound up with React. If you need less data you must reduce data before set the state.
const reducedBuildings = [];
fetch(`http://localhost:1001/api/energyprograms/${energyProgramId}/buildings/?results=10`)
.then(res => res.json())
.then(json => {
json.forEach(building => {
if (reducedBuildings.length < 10) {
reducedBuildings.push(building);
}
});
this.setState({
isLoaded: true,
buildings: reducedBuildings,
})
});

Categories