Javascript fetch api - javascript

i'm trying to assign the variable countries to the response of the fetch api but when i print out countries i get undefined ? can anyone explain to me why ? and a solution if it is possible.
async function getCountries(url) {
const data = await fetch(url);
const response = await data.json();
return response;
}
let countries;
document.addEventListener('DOMContentLoaded', () => {
getCountries('https://restcountries.eu/rest/v2/all')
.then(res => countries = res)
.catch(err => console.log(err));
})
console.log(countries);

function getCountries(url) {
return new Promise((resolve,reject)=>{
fetch(url).then(res => {
//You can parse the countries from the api response here and return to the
//event listener function from here using the resolve methood call parameter
resolve(res);
})
.catch(err => console.log(err));
})
}
document.addEventListener('DOMContentLoaded', () => {
getCountries('https://restcountries.eu/rest/v2/all')
.then(res => {
//the returned value after api call and parsing will be available here in res
})
})
Or if you dont want another function for this one you can directly get it using the following way,
document.addEventListener('DOMContentLoaded', () => {
let countries;
fetch('https://restcountries.eu/rest/v2/all')
.then(res => {
//the returned value after api call and parsing out the countries hereit self
countries = res.data.countries;
})
})

Related

Uncaught TypeError: Cannot read property 'then' of undefined at HTMLFormElement.<anonymous>

All code work good, but when I put then to the returned module all code crashes and throws error. Is the problem from that the export is function? If it is not from the function may someone explain why?
This is the module
export default {
search: function(searchTerm, searchLimit, sortBy) {
fetch(
`http://www.reddit.com/search.json?q=${searchTerm}&sort=${sortBy}&limit=${searchLimit}`
)
.then(res => res.json())
.then(data => data.data.children.map(data => data.data))
.catch(err => console.log(err));
}
};
This is actual main JavaScript file
import reddit from "./redditApi";
const searchForm = document.querySelector("#search-form");
const searchInput = document.querySelector("#search-input");
// form eventlistener
searchForm.addEventListener("submit", e => {
e.preventDefault();
// get search term
const searchTerm = searchInput.value;
// get sort
const sortBy = document.querySelector('input[name="sortby"]:checked').value;
// get limit
const searchLimit = document.querySelector("#limit").value;
// check input
if (searchTerm === "") {
// show message
showMessage("Please add a search Term!", "alert-danger");
}
// clear input
searchInput.value = "";
// search reddit
reddit.search(searchTerm, searchLimit, sortBy).then(results => {
console.log(results);
});
});
fetch returns a promise, but search doesn't have any return statement at all.
After you call catch on it, the promise is discarded.
If you want to use it outside the search function then you need to return it.
If you intend to do that
reddit.search(searchTerm, searchLimit, sortBy)
.then(results => {
console.log(results);
})
.catch(error => {
console.log(error);
});
you should wrap fetch inside a Promise.
example:
export default {
search: (searchTerm, searchLimit, sortBy) => {
return new Promise((resolve, reject) => {
fetch(`http://www.reddit.com/search.json?q=${searchTerm}&sort=${sortBy}&limit=${searchLimit}`)
.then(res => res.json())
.then(data => resolve(data.data.children.map(data => data.data)))
.catch(err => reject(err));
});
}
};

how to save promise chaining event in javaScript

I'm making a promise chained fetch call to an API and using it to get the desired data from it. I can't figure out how to save the resulting array which I am logging to the console and then export it to use it another javaScript file.
fetch('http://api.waqi.info/feed/delhi/?token=66cc9b64ec97aff8a78266ca41b082edf3e9a65a')
.then(res => res.json())
.then(response_body => Object.values(response_body.data.iaqi).map(({v}) => v))
.then(console.log)
You can just export your fetch call in a function and return your Promise.
Here is a minimal example:
// == api.js ==
export const getData = () => {
return fetch('http://api.waqi.info/feed/delhi/?token=66cc9b64ec97aff8a78266ca41b082edf3e9a65a')
.then(res => res.json())
.then(response_body => Object.values(response_body.data.iaqi).map(({v}) => v))
.then(console.log)
}
// == otherfile.js ==
import { getData } from './api.js'
const myFunction = () => {
getData().then(res => {
// do your stuff
})
}
// Async/await style
const myFunction = async () => {
const res = await getData()
}

Why fetching(API) gives me undefined?

I created an API using Flask, and it is working perfectly when using it in Postman, giving me JSON.
Anyways, when I try to fetch it in javascript, it is giving me undefined:
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response => {
response.json();
})
.then(data => {
console.log(data);
});
};
getData();
As I said, when I try to log the data, it prints
undefined
You need to return your json data(return response.json();), fixed snippet:
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
console.log(data);
});
};
getData();
You get undefined because you dont return anything. Every function returns undefined if you dont return something.
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response =>{
return response.json();
})
.json() is asynchronous too so you will need an .then() block after ur function call.
getData().then( res => {
console.log(res);
});

how to retrieve results after api call which is returning a promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a module that invokes a service
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(json => (getData = json));
export {getData };
I try to log to console the result (and put it on an HTML page) like this
import { getData } from "./api";
const app = document.querySelector("#target");
let data = getData()
.then(res => res.map(r => r.title).join("\n"))
.then(res => (data = res));
console.log(data);
app.innerHTML = data;
However, I get an unresolved promise like this [object Promise]
I've tried a few variations which also don't work
// none of these work don't work
// .then(async res => data = await res);
// .then(res => (data = Promise.resolve(res)));
Any suggestions as to what I am doing wrong?
Firstly, you shouldn't use the second then in getData - that's the result, and it reassigns your variable. Then change some other things in your code - syntax errors and wrong methods mostly:
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts").then(response => response.json());
const app = document.querySelector("#target");
getData()
.then(res => res.map(r => r.title).join("<br>"))
.then(res => app.innerHTML = res);
<p id="target"></p>
i think you have to 'return' response.json() and then exec another then()
and also is better to include cathc to see problems
read
Making fetch requests
https://developer.mozilla.org/it/docs/Web/API/Fetch_API/Using_Fetch
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts")
.then(function (response) {
return response.json();
})
.catch(function (err) {
console.log(err);
});
const app = document.querySelector("#target");
getData()
.then(res => res.map(r => app.innerHTML += r.title));

Async and Await not working in Axios React

i have a problem:
I want that my axios make the requistion and after it makes the this.setState with the result saved in a variable.
My code:
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
async axios.get(`/api/status/${i.mail}`)
.then(res => {
mails.push(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.log(err))
})
}))
.catch(err => console.log(err))
}
But it gives error syntax.
Best explanation: I want saved all results of the map in the variable mails and later to use the setState to changes the result of just a time.
Someone could tell me where i'm wandering? Please.
You are using async await at the wrong places. async keyword must be used for a function that contains asynchronous function
await keyword needs to be used for an expression that returns a Promise, and although setState is async, it doesn't return a Promise and hence await won't work with it
Your solution will look like
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, async () => {
const mails = await Promise.all(this.state.employees.map(async (i) => { // map function contains async code
try {
const res = await axios.get(`/api/status/${i.mail}`)
return res.data;
} catch(err) {
console.log(err)
}
})
this.setState({ mails })
}))
.catch(err => console.log(err))
}
It's not a good practice to mix async/await with .then/.catch. Instead use one or the other. Here's an example of how you could do it using ONLY async/await and ONLY one this.setState() (reference to Promise.each function):
componentDidMount = async () => {
try {
const { data: employees } = await axios.get('/api/employee/fulano'); // get employees data from API and set res.data to "employees" (es6 destructing + alias)
const mails = []; // initialize variable mails as an empty array
await Promise.each(employees, async ({ mail }) => { // Promise.each is an asynchronous Promise loop function offered by a third party package called "bluebird"
try {
const { data } = await axios.get(`/api/status/${mail}`) // fetch mail status data
mails.push(data); // push found data into mails array, then loop back until all mail has been iterated over
} catch (err) { console.error(err); }
})
// optional: add a check to see if mails are present and not empty, otherwise throw an error.
this.setState({ employees, mails }); // set employees and mails to state
} catch (err) { console.error(err); }
}
This should work:
componentDidMount() {
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
axios.get(`/api/status/${i.mail}`)
.then( async (res) => { // Fix occurred here
let mails = [].concat(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.log(err))
})
}))
.catch(err => console.log(err))
}
You put async in the wrong place
async should be placed in a function definition, not a function call
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
axios.get(`/api/status/${i.mail}`)
.then(async (res) => {
mails.push(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.log(err))
})
}))
.catch(err => console.log(err))
}

Categories

Resources