Promise pending, fulfilled not returning - javascript

Trying to display data from a json.
When I run my functions on the console, it shows:
PromiseĀ {} and [[PromiseState]]: "fulfilled"
But not actually returning anything.
getJobs = async () => {
try{
response = await fetch("./data.json");
const data = await response.json();
return data;
} catch(error){
console.log('Error getting data', error)
}
}
renderJobs = async () => {
const jobs = await getJobs();
const view = `
<div class='card-company'>
${jobs.map(companyName => `
<p>${companyName.company}</p>
`).join('')}
</div>
`
return view
}
I have all the p tags I need inside the property [[PromiseResult]] but nothing displaying in the document.
I have not been able to find anything like this, also if there's anything to improve in this snippet, I appreciate the feedback.
Thank you.

Since these are async functions, you need to use await to get their final return value.
To log the HTML string, you can use console.log(await renderJobs());, and wherever you are running renderJobs() in your code, you will need to use await to get the HTML string as well.
Using console.log(renderJobs()); will return the promise pending message you described because async functions return a promise, not the result of the promise. Using await returns the fulfilled value of the promise it is used on.

Looks like an improper template to me. I'm not seeing a use for it in this case, anyways. Should be more like:
const M = tag=>document.createElement(tag);
const renderJobs = async () => {
const jobs = await getJobs(), frag = document.createDocumentFragment();
let d;
for(let o of jobs){
d = M('div'); d.className = 'card-company'; d.textContent = o.company;
frag.appendChild(d);
}
// you could append frag here or return and append later
return frag;
}

try it
getJobs = () =>
new Promise((resolve) => {
fetch("./data.json").then((data) => {
resolve(data);
});
});
renderJobs = async () => {
const jobs = await getJobs();
const view = (
<div class="card-company">
${jobs.map((companyName) => <p>${companyName.company}</p>).join("")}
</div>
);
return view;
};

I see an issue with how you are not handling an error. You need to return reject or throw an error. Otherwise, the promise will never be resolved
getJobs = async () => {
try {
const response = await fetch('./data.json')
const data = await response.json()
return data
} catch (error) {
console.log('Error getting data', error)
return Promise.reject(error)
}
}
renderJobs = async () => {
let jobs = []
try {
jobs = await getJobs()
} catch(error) {
console.log('Error getting data', error)
}
const view = `
<div class='card-company'>
${jobs
.map(
(companyName) => `
<p>${companyName.company}</p>
`
)
.join('')}
</div>
`
return view
}

Related

How can I fetch an api inside a loop and wait some seconds after each fetch?

Hello everyone and thank you for taking your time to read through my question.
I am currently sitting on my first react native app where I fetch a lot of data with an API.
I want to iterate through a loop and fetch data at every iteration. Unfortunately I get the "Too many requests error". Reason is, I can only fetch every 5 seconds according to my API Provider.
Therefore I tried to solve the problem with setTimeout as recommended on other posts. But it doesn't work. I can put the setTimeout function everywhere in the code and it always waits 5 seconds. Besides when I put it in the loop (where I think it belongs). Then it just does nothing and iterates normally through the loop.
How would you solve that?
function Overview() {
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function fetchETFData(props) {
try {
const response = await fetch("URL_API" + props);
const testData = await response.json();
console.log(testData);
} catch (error) {
console.error(error);
}
}
async function userData() {
try {
const response = await fetch("URL_Database");
// Fetch data from a database and then iterate threw that data and fetch with that data from an API
const userDataFetch = await response.json();
for (var key in userDataFetch) {
userDataFetch[key].forEach(async function (element) {
await sleep(5000);
let fetchSymbol = element.symbol;
fetchETFData(fetchSymbol);
});
}
} catch (error) {
console.error(error);
}
}
userData();
return (
<div>
<Button
onPress={ShareOfPositions}
title="Calculate Shares"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</div>
);
}
In your for loop, change await sleep(5000) to sleep(5000 * (index+1)) where index is the current element index that forEach gives us. This way you make sure between each there is 5s as you wanted:
userDataFetch[key].forEach(async function (element, index) {
await sleep(5000 * (index+1));
let fetchSymbol = element.symbol;
fetchETFData(fetchSymbol);
});
And here his your whole component where I added the function in a useEffect to make sure it runs only once:
import {useEffect} from "react";
function Overview() {
useEffect(() => {
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function fetchETFData(props) {
try {
const response = await fetch("URL_API" + props);
const testData = await response.json();
console.log(testData);
} catch (error) {
console.error(error);
}
}
async function userData() {
try {
const response = await fetch("URL_Database");
const userDataFetch = await response.json();
for (var key in userDataFetch) {
userDataFetch[key].forEach(async function (element, index) {
await sleep(5000 * (index+1));
let fetchSymbol = element.symbol;
fetchETFData(fetchSymbol);
});
}
} catch (error) {
console.error(error);
}
}
userData();
}, []);
return (
<div>
<Button
onPress={ShareOfPositions}
title="Calculate Shares"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</div>
);
}

How to handle "Promise { <pending> }" in javascript

I have this function in javascript
const getData = async() => {
try {
const serviceResponse = await someService("userId")
return serviceResponse
} catch (error) {
console.log(error);
}
}
const data = getData()
console.log(data)
Whenever I am running this I am getting this in console
Promise { <pending> }
But when I am print data in the function itself I am getting the desired value
const getData = async() => {
try {
const serviceResponse = await someService("userId")
console.log.(serviceResponse)
} catch (error) {
console.log(error);
}
}
getData()
The following function is what I am importing from defined in another another
exports.someService = async(date,locationId,workerType) => {
const value = await Attendance.find({})
return value
}
Please can someone explain what is happening ?
you need to await the promise from getData() too -
const data = await getData()

Result always undefined when return the result Nodejs

hi i got some problem here i want to return the result after getting target content on the getnada email, but its always return undefined, can somebody help me here.
const getEmailData = async (getExtention) => {
// return getExtention
await axios
.get(`https://getnada.com/api/v1/inboxes/${getExtention}`)
.then(async (res) => {
const getEmailCount = await res.data.msgs.length
if (parseInt(getEmailCount) >= 1) {
// console.log('Berhasil berhasil Hore')
const getDataEmail = await axios.get(
`https://getnada.com/api/v1/messages/html/${res.data.msgs[0].uid}`
)
if (getDataEmail) {
console.log('Data berhasil')
const getOTPEmail = await Promise.all(getDataEmail.data)
return getOTPEmail
} else {
console.log('Data Gagal')
}
}
})
.catch(() => {
getEmailData(getExtention)
})
}
here is the code of my procces on getting The content i want to get
but after i return the getOTPEmail its always undefined
the result i declare is like this
const getDataOTP = await getEmailData(getExtention)
console.log(getDataOTP)
can someone explain me whats wrong with this code ?
One easy way to do it would be to move the code from the .then callback "outside" as follow :
const getEmailData = async (getExtention) => {
// return getExtention
try {
let res = await axios
.get(`https://getnada.com/api/v1/inboxes/${getExtention}`);
const getEmailCount = await res.data.msgs.length
if (parseInt(getEmailCount) >= 1) {
// console.log('Berhasil berhasil Hore')
const getDataEmail = await axios.get(
`https://getnada.com/api/v1/messages/html/${res.data.msgs[0].uid}`
)
if (getDataEmail) {
console.log('Data berhasil')
const getOTPEmail = await Promise.all(getDataEmail.data)
return getOTPEmail
} else {
console.log('Data Gagal')
}
}
} catch (e) {
getEmailData(getExtension);
}
}
Also, you will notice that this part const getEmailCount = await res.data.msgs.length probably doesn't work as you would expect because length isn't a promise.
But why isn't it working as is ?
Using .then is using a callback on the promise return by axios.get so your getEmailData function doesn't return anything. It is calling axios.get which is asynchronous and provide a callback once the promise has been resolved, and leaving.
Is there a way to make this work using .then ?
There is, with the following steps :
initialize a Promise in getEmailData
remove the await in front of axios.get call.
call resolve from the initialized Promise in .then callback
Pseudo-Code :
const getEmailData = async (getExtension) => {
return new Promise((resolve) => {
axios.get().then((res) => {
resolve(res);
})
});
}
But it is way easier to write, easier to read and cleaner to use await, otherwise it's becoming a callback hell :)
I think the error is here
if (parseInt(getEmailCount) >= 1) {
// console.log('Berhasil berhasil Hore')
const getDataEmail = await axios.get(
`https://getnada.com/api/v1/messages/html/${res.data.msgs[0].uid}`
)
if (getDataEmail) {
console.log('Data berhasil')
const getOTPEmail = await Promise.all(getDataEmail.data)
return getOTPEmail
} else {
console.log('Data Gagal')
}
because you defined the 'getDataEmail' variable inside the if statement and you want to use it outside it .
so ,I think you have to do it like this
let getDataEmail ;
if (parseInt(getEmailCount) >= 1) {
// console.log('Berhasil berhasil Hore')
getDataEmail = await axios.get(
`https://getnada.com/api/v1/messages/html/${res.data.msgs[0].uid}`
)
if (getDataEmail) {
console.log('Data berhasil')
const getOTPEmail = await Promise.all(getDataEmail.data)
return getOTPEmail
} else {
console.log('Data Gagal')
}

how to return multiple values from an asynchronous function to use in another function

I am getting login and password values in an asynchronous function and returning using destructuring. But when I try to use the data in another function, it outputs - undefined. Help please. In what the problem
async function authWithLoginAndPassword() {
const response = await fetch('');
const data = await response.json();
const logUser = data[0].login;
const passwordUser = data[0].password;
return { logUser, passwordUser }
}
submit.addEventListener('click', () => {
let register = authWithLoginAndPassword();
console.log(register.logUser, register.passwordUser)
})
All async functions return a promise that resolves to whatever value you return from that function. So, when you call authWithLoginAndPassword(), you have to use either .then() or await to get the resolved value from the promise that the function returns:
submit.addEventListener('click', async () => {
try {
let register = await authWithLoginAndPassword();
console.log(register.logUser, register.passwordUser)
} catch(e) {
// catch errors
console.log(e);
}
});
or
submit.addEventListener('click', () => {
authWithLoginAndPassword().then(register => {
console.log(register.logUser, register.passwordUser)
}).catch(err => {
console.log(err);
});
});

Variable Retains Original Value Despite Having New Value Earlier and Further within a Function

let getProjects = function() {
try {
return axios.get('https://app.asana.com/api/1.0/projects/')
} catch (error) {
console.error(error)
}
}
let getTasks = function(project) {
try {
return axios.get('https://app.asana.com/api/1.0/projects/'+project+'/tasks')
} catch (error) {
console.error(error)
}
}
async function getAsanaData() {
let projects = await getProjects()
projects = projects.data.data
projects.map(async (project) => {
//project.attachments = []
let tasks = await getTasks(project.gid)
if(tasks != undefined){
tasks = tasks.data.data
project.tasks = tasks
//console.log(projects)
}
})
console.log(projects)
return projects
}
Promise.try(() => {
return getAsanaData();
}).then((result) => {
//console.log(util.inspect(result, {showHidden: false, depth: null}))
//var asanaData = safeJsonStringify(result);
//fs.writeFile("thing.json", asanaData);
})
.catch(err=>console.log(err))
In getAsanaData(), projects has a new value after project.tasks = tasks.
However, it's original value is printed by console.log(projects) before return projects.
This of course also means that the original value rather than the necessary new value will be returned.
What is the cause and how do I resolve this?
Try this:
async function getAsanaData() {
let projects = await getProjects()
return Promise.all(projects.data.data.map(async (project) => {
let tasks = await getTasks(project.gid)
project.tasks = !!tasks ? tasks.data.data : project.tasks
return project
}))
}
This will go through the async calls to getTasks and return for each the project. Then you should get them all resolved via Promise.all

Categories

Resources