Javascript Fetch Function returns [object Promise] - javascript

I'm currently working on a project, which includes a website, built and run by Django. On this website, I'm trying to load data through fast API and try to load this data through JavaScript and the Fetch API. But I always get instead of the Data provided through the API, an [object Promise]. I've tried many different methods but none seem to work.
I've tried for example:
document.getElementById("1.1").innerHTML = fetch('the URL')
.then(response => response.text())
or
document.getElementById("1.1").innerHTML = fetch('the URL')
.then(response => response.text())
.then((response) => {
console.log(response)
})
and many other methods. I've also checked and the API request works perfectly, returning a string.

You want the setting of the html to appear when you log the final response, eg:
fetch('the URL')
.then(response => response.text())
.then((response) => {
console.log(response)
document.getElementById("1.1").innerHTML = response
})
Other ways including making the whole of the response promise to be fulfilled:
const getData = async (url) => {
const res = await fetch(url)
const resText = await res.text()
return resText
}
const addTextFromUrl = async (url, element) => {
const text = await getData(url)
element.innerHtml = text
}
addTextFromUrl('theUrl', document.getElementById("1.1"))
Generally it is a little easier to follow the async/await syntax when learning, but you should always try/catch any errors.

Every .then call does return a new promise. So
You need to assign value in a callback or use async/await
fetch('the URL')
.then(response => response.text())
.then((response) => {
document.getElementById("1.1").innerHTML = response
})
or do it inside an async function
async function getHtml() {
document.getElementById("1.1").innerHTML = await fetch('the URL')
.then(response => response.text())
}
getHtml();
W/o using then
async function getHtml() {
const response = await fetch('the URL');
const html - await response.text();
document.getElementById("1.1").innerHTML = html;
}
getHtml();

Related

Not getitng the same response in postman and fetch

I have this function to make a request to gyphy api
const getGifs = async () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp = await fetch(url)
.then(response => console.log(response));
}
In postman I get a json with the searched data but in javascript I get a response object, how can I get the searched data?
The fetch API does not return the raw response a such. The object you're getting is one that can be transformed into what you need. Since you're expecting JSON data, then your code should be:
const getGifs = async () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp = await fetch(url)
.then(response => response.json())
.then(jsonData => console.log(jsonData)) // the response you're expecting
}
The .json() method returns a Promise that resolves with your JSON parsed data.
According to the giphy api doc, the search endpoint returns a data element, which is an array of gifs. Just inspect your response object and see if it has a data element, then log response.data, not the full response
.then(response => console.log(response.data));
you are returning undefined because you are returning console.log() which is not right. Change it to response.body()
const fetch = require("node-fetch")
const getGifs = () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp =fetch(url)
.then(response => response.data);
return resp;
}
console.log(getGifs());

No response returned from fetch

I am trying to get data from the API and it doesnot return any value. I have tried to put the apiUrl in the browser directly it works there. Even a get request via postman returns request.
fetch(apiUrl)
.then((response) => {
let data = JSON.parse(response)
console.log(data)
return data;
})
Also in Chrome debugger, there is no request in the network tab as well. I have used the same code earlier to get the response.
Calling the API with Fetch gives a promise, and converting it to JSON will return yet another promise, which you need to "await" for again. This is how it should look like
fetch(URL)
.then(response => response.json())
.then(json => console.log(json))
fetch(apiUrl)
.then((response) => {
return response.json().then( res => {
let data = res;
console.log(data)
return data;
})
})
try this

Performing Fetch Request in a Loop

I am working on an application that returns a list of ids from first fetch request. After getting the ids, I have to loop through the ids and get details of each item and then display it on the screen.
fetch(TOP_STORIES)
.then(function(response){
return response.json()
}).then(function(storyIds){
// storyIds is [22,33,44,55,66,77,88,99,123,213,342,45456,778,888]
// is this the best way to fetch all the details of the story
storyIds.forEach(function(storyId){
let storyDetailsURL = `https://someurl/v0/item/${storyId}.json?print=pretty`
fetch(storyDetailsURL)
.then((response) => response.json())
.then((story) => {
displayStory(story)
})
})
})
My question is that is looping the best way to get the results?
UPDATE: Promise.all is giving me issues:
UPDATE: Using Async and Await
async function fetchTopHeadlinesAsyncAwait() {
let response = await fetch(TOP_STORIES)
let storyIds = await response.json()
for(let storyId of storyIds) {
console.log(storyId)
let storyDetailsURL = `someurl/er/tg/${storyId}.json?print=pretty`
let response = await fetch(storyDetailsURL)
let story = await response.json()
displayStory(story)
}
}
You can use Promise.all functionality to fetch a list of async actions. They will be completed when all are successful.
Here is example of your code with Promise all, let me know how it works :)
const fetchStories = () => {
let response = await fetch(TOP_STORIES);
let storyIds = await response.json();
let urls = [];
storyIds.forEach(function(storyId) {
urls.push(`https://someurl/v0/item/${storyId}.json?print=pretty`);
});
Promise.all(
urls.map(url =>
fetch(url)
.then(response => response.json())
.catch(err => console.error(err))
)
).then(stories => stories.forEach(story => displayStory(story)));
}

Why can't I store the result of a promise (or a chained promise) in a variable?

This is a silly question but can you explain what is wrong with this code?
Why can't I perform this?
const fetch = require('node-fetch');
const fetchProm = (() => {
return fetch('https://api.github.com/users/github');
}).then((response) => {
return response.json();
}).then((json) => {
console.log(json)
});
Declaring a function is not the same as calling one
You are not calling the function that returns the promise, just declaring it. You'll need to add an additional set of parentheses before the first .then() in order to actually call the function:
const fetch = require('node-fetch');
const fetchProm = (() => {
return fetch('https://api.github.com/users/github');
})().then((response) => {
return response.json();
}).then((json) => {
console.log(json)
});
If you want to call everything at a later time, you need to place the whole thing in its own function where the promises get handled in an isolated scope:
const fetch = require('node-fetch');
const fetchProm = () => {
fetch('https://api.github.com/users/github')
.then(response => response.json())
.then(json => console.log(json));
};
fetchProm();

XML request and response with fetch?

The Postal Service has an API that allows you to send an xml request with package weight, travel info, etc. It will return back an xml response.
How do I handle the xml response? I either need to parse the xml on the client-side, or more preferably, put the xml in a variable that I can send to my laravel backend for parsing.
Btw, I'm using react and laravel.
getPostagePrice = () => {
fetch('http://production.shippingapis.com/ShippingApi.dll?API=RateV4&XML=<RateV4Request USERID="XXXXXXXXXXX"><PackageID="1ST"><Service>PRIORITY</Service><ZipOrigination>44106</ZipOrigination><ZipDestination>20770</ZipDestination><Pounds>1</Pounds><Ounces>8</Ounces><Container>NONRECTANGULAR</Container><Size>LARGE</Size><Width>15</Width><Length>30</Length><Height>15</Height><Girth>55</Girth></Package></RateV4Request>', {
method: 'get',
}).then((response) => {
console.log(response.text());
}).then(str => (new window.DOMParser()).parseFromString(str, "text/xml")
).then(data => console.log(data));
}
Response.text() returns a Promise, chain .then() to get the Promise value of .text() call.
If you are expecting a Promise to be returned from getPostagePrice function, return fetch() call from getPostagePrice() call.
getPostagePrice = () => {
fetch('/path/to/server')
.then(response => response.text())
.then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
.then(data => console.log(data));
}
Also with async/await you can do the same without lost your scope (remember that if you use .then, you only can work INSIDE the callback function).
async function display(){
const xmlFetch = await fetch("./yourXMLorXSL.xml")
const xmlText = await xmlFetch.text()
const xml = await (new window.DOMParser()).parseFromString(xmlText, "text/xml")
console.log(xml)
}

Categories

Resources