Axios get function undefined when accessing outside, cannot use async and await - javascript

The following code gives me undefined. I tried fixing it with various async/await but it came up as an error. Anyone know how to fix? EDIT: To be more specific, I need the value of "output" stored. I am using console.log just to guarantee it is getting the information I need it to have.
const URL = 'https://api.1inch.exchange/v3.0/1/quote?fromTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&toTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&amount=1&protocols=';
function getAmount(){
axios.get(URL).then((response) => {
//console.log(response.data)
const output = response.data.toTokenAmount
//console.log(output)
return output
})
//console.log(output)
}
console.log(getAmount());

You must return promise inside getAmountfunction. Also you need to wait on that promise when calling getAmount function.
This should work:
const URL = 'https://api.1inch.exchange/v3.0/1/quote?fromTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&toTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&amount=1&protocols=';
function getAmount(){
return axios.get(URL).then((response) => {
const output = response.data.toTokenAmount
return output; })
}
getAmount().then(toTokenAmount => console.log(toTokenAmount));

Related

Jest, mocking return from await, I see results in console, but expect still fails

I have a pretty simple example of a mock working, updating the value correctly, but my test still fails.
fetchStuff.js:
const fetchStuff = async (entity, service) => {
entity = await service.get();
console.log('entity is an expected result!', entity); // this consoles out the expected value correctly.
}
fetchStuff.spec.js:
it('should...', () => {
const expected = 'this will show up in console';
const service.get = jest.fn().mockImplementation(() => expected);
let entity;
fetchStuff(entity, service);
expect(entity).toEqual(expected) // entity = 'undefined'
});
Every time, I see that console.log in the function is printing out the expected result, but some reason the expect(entity) is always undefined.
I've tried stuff like with flush-promise, I've tried removing the await. I've even seen the done(), technique, where we pass done in to it, ie it('should...', done => {...})
Not sure why I cannot get the correct expected, even tho the console is showing the expected result.
PS. I understand this is not respecting functional paradigm or pure functions. Please ignore that.
You are using an asynchronous function, but testing right away, before the promise is resolved. You need an async/await in your test, if you are using asynchronous calls, like your await in the main function.
it('should...', async () => {
const expected = 'this will show up in console';
const service.get = jest.fn().mockImplementation(() => expected);
let entity;
await fetchStuff(entity, service);
expect(entity).toEqual(expected) // entity = 'undefined'
});
However, as per the comment on your question, the code may not be returning what you expect, so this change for async/await will not solve the problem on its own.
const fetchStuff = async (entity, service) => {
entity = await service.get();
console.log('entity is an expected result!', entity);
return entity;
}
it('should...', async () => {
const expected = 'this will show up in console';
const FakeService = jest.fn().mockResolvedValue(expected),
const entity = await FakeService();
expect(entity).toBe(expected) ;
});

new promise inside a async function in order to grab the value outside of the async function

I am returning a new Promis inside a async function that is doing a request to a api, I can console log the request from the api just fine inside the function. But when I try and resolve the same line I consoled document.sold it does not work. I expected the checkPriceId variable to return a promise which I could then catch with .then, but that does not seem to work. I have also tried using promise.all around the documents.forEach loop to no avail.
Any help would be greatly appreciated.
Here's the code
const checkPriceId = async test => {
return new Promise((resolve, reject) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`
client.fetch(query, {}).then(documents => {
documents.forEach(document => {
//console.log(document.sold)
resolve(document.sold)
})
})
})
}
checkPriceId.then(test => {
console.log(test) // does nothing
})
console.log(checkPriceId) // just returns a async function
checkPriceId()
Why use the Promise constructor at all? client.fetch already returns a promise, and you're also inside an async function which also returns a promise. Assuming all documents have a .sold that you're trying to get back in an array:
const checkPriceId = async () => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`
const documents = await client.fetch(query, {})
return documents.map(({ sold }) => sold)
}
checkPriceId.then((soldList) => {
console.log(soldList)
})
This also removes the test argument to checkPriceId since it wasn't being used.
As #blex mentinoned, you are not calling checkPriceId on line 13.
However, as also mentioned by #grodzi, you cannot resolve your promise multiple times. Once the resolve fn is called once (on line 7), subsequent calls will be ignored.
Since mixing Promises and async the way you are can be verbose and opaqueI'd suggest you just use async/awiat here. This will greatly help your code readability.
Here's a fixed example:
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map(document => document.sold);
}
checkPriceId().then(test => {
console.log(test) // this will log the return value from line 7
})

How to get neo4j query result returned from .then with node js

I would need to get the data returned by using the Neo4j driver for Node JS. My problem is, that i can print the value of 'online' out on console inside the .then call but i can't seem to get access to it outside of that part - I have tried returning record.get('onl'), assign it to a pre-defined variable outside the function but nothing works - all i get as result if i try to, for example, print the value of online out at the last line in this snippet, is Promise { <pending> }. I suppose I don't do the promise handling right, and I looked up lots of tutorials and examples, but I can't work it out. So: how could i assign the returned data (record.get('onl')) to var online and get actual result instead of the promise?
Thanks in advance :)
var online = session.run(cyp1, param).then(results => {
return results.records.map(record =>{
console.log(record.get('onl'))
return record.get('onl')
})
}).then(()=>{
session.close()
});
console.log(online)
Currently, you are assigning var online as a 'Promise Chain' & not a 'Resolved Promise'. You could use Async/Await this will allow you to write async code in a synchronous manner.
async function getRecords(){
const records = await session.run(cyp1, param);
return records.map(record => record.get('onl'))
}
const online = await getRecords();
Use try/catch/finally
try {
const online = await getRecords();
} catch (error) {
// do something
} finally {
await session.close()
}
If you wanted to continue using .then()
You need to use 'Promise Chaining' and pass the value 'Down the chain', this results in complex 'Callback'/'Promise Chain' hell.
session.run(cyp1, param).then(results => {
return results.records.map(record => record.get('onl'))
}).then((online)=> {
console.log(online)
}).catch(() => {
// do something
}).finally(() => {
session.close()
});

How do I store a value from a petition?

I want to get a value from an API and save that value for later, but I'm having troubles.
I get the result I want when I use console.log(), but when I do exactly the same thing with "return()" I get this result:
Promise{< resolved >:"The value I want"}
I'll show you my code:
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
const data = await response.json()
console.log("async/await based")
console.log(data.USD.transferencia)
}
When I call getDataAA() I get what I want in the console, but I want to store that value in order to use it, so I changed "console.log(data.USD.transferencia)" for "return(data.USD.transferencia)".
Then I do something like this in order to save the value:
let dolarPrice = getDataAA()
Why when I use "console.log" I get the value but when I use "return" I get also the promise?
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
return response.json()
}
let response = await getDataAA();
console.log(response);
-- EDITED
so this one another example how use it.
the async method (getDataAA) have to return something.
everytime you need to call an async method you have to use await (
if you wait until it's completed)
everytime you use await the method must be async.
<!DOCTYPE html>
<html>
<script type="text/javascript">
var f = async () => {
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
return response.json()
}
let response = await getDataAA();
console.log(response);
}
f();
</script>
</html>
I discovered I way to solve this! I defined a variable outside the function and then the function stored the value I wanted inside that variable. This is my code:
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
const data = await response.json()
console.log("async/await based")
dolarPrice = (data.USD.transferencia)
}
let dolarPrice
getDataAA()
That way I stored the value inside the "dolarPrice" variable. Thanks all the people who answered my question, I found the solution thanks to all of you.

Promise.all results are as expected, but individual items showing undefined

First of all, there are some issues with console.log in Google Chrome not functioning as expected. This is not the case as I am working in VSCode.
We begin with two async calls to the server.
promise_a = fetch(url)
promise_b = fetch(url)
Since fetch results are also promises, .json() will needed to be called on each item. The helper function process will be used, as suggested by a Stackoverflow user -- sorry lost the link.
let promiseResults = []
let process = prom => {
prom.then(data => {
promiseResults.push(data);
});
};
Promise.all is called. The resulting array is passed to .then where forEach calls process on item.json() each iteration and fulfilled promises are pushed to promiseResults.
Promise.all([promise_a, promise_b])
.then(responseArr => {
responseArr.forEach(item => {
process(item.json());
});
})
No argument is given to the final .then block because promiseResults are in the outer scope. console.log show confusing results.
.then(() => {
console.log(promiseResults); // correct results
console.log(promiseResults[0]); // undefined ?!?
})
Any help will be greatly appreciated.
If you are familiar with async/await syntax, I would suggest you not to use an external variable promiseResults, but return the results on the fly with this function:
async function getJsonResults(promisesArr) {
// Get fetch promises response
const results = await Promise.all(promisesArr);
// Get JSON from each response promise
const jsonResults = await Promise.all(results.map(r => r.json()));
return jsonResults
}
This is usage example:
promise_a = fetch(url1)
promise_b = fetch(url2)
getJsonResults([promise_a, promise_b])
.then(theResults => console.log('All results:', theResults))
Use theResults variable to extract necessary results.
You can try this, it looks the array loop is not going properly in the promise env.
Specifically: the promiseResults is filled after you are logging.
var resultAll = Promise.all([promise_a, promise_b])
.then(responseArr => {
return Promise.all(responseArr.map(item => return item.json()));
});
resultAll.then(promiseResults => {
console.log(promiseResults);
});

Categories