How can I use async/await instead of a promise (.then) - es6-promise

I'm trying to use async/await in my project instead of .then, but it's throwing me an error
here is my code:
export const registerUser = (userData, history) => async dispatch => {
axios
.post('/api/users/register', userData)
await (res => history.push('/login'))
.catch(err => dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
and this is the error i get back
Unhandled Rejection (TypeError): (intermediate value).catch is not a function

await isn't a function that you replace then() with. It is a keyword that you put before an expression that resolves as a promise. When you use it, you also replace the catch() method with a regular try/catch.
export const registerUser = (userData, history) => async dispatch => {
try {
await axios.post('/api/users/register', userData);
history.push('/login');
} catch (err) {
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};

Related

get real-time json data from twilio runtime with axios

I am trying to achieve real-time data from twilio server-less function. I am using a boilerplate function edited a little bit.What I want is json data in server and voice response in call consecutively .but the following code is not sending json data to server.
const axios = require('axios');
exports.handler = function (context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.say('you are welcome ');
const instance = axios.create({
baseURL: 'http://fafc4eac4162.ngrok.io/',
timeout: 3000,
});
instance
.post('/test', {
id: 1,
title: 'Twilio'
})
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
return callback(error);
});
return callback(null, twiml);
};
It shows below error,but it sends data successfully if I do not use the voice response callback return callback(null, twiml) and rather use simple return callback(null, response.data);
{"message":"timeout of 3000ms exceeded","name":"Error","stack":"Error: timeout of 3000ms
exceeded\n at createError (/var/task/node_modules/axios/lib/core/createError.js:16:15)\n
at RedirectableRequest.handleRequestTimeout
(/var/task/node_modules/axios/lib/adapters/http.js:280:16)\n at Object.onceWrapper
(events.js:286:20)\n at RedirectableRequest.emit (events.js:198:13)\n at
Timeout._onTimeout (/var/task/node_modules/follow-redirects/index.js:166:13)\n at
ontimeout (timers.j...
The return callback(null, twiml); should be in the .then block.
.then((response) => {
console.log(JSON.stringify(response.data));
return callback(null, twiml);
})
Also, the error indicates the 3000ms timeout is hit, is your application returning a 200-OK?

Stop another .then() execution in chain of promises

I have programme in nodejs & mysql like below
db.query()
.then(1)
.then(2)
.then(3)
.catch()
I am checking a value from database in then(1) and trying to return response from there.In then(2) , I am executing another code that uses some data from result of then(1) and so on..
My problem: When returning response from then(1), catch() is calling(because then(2) have error, not getting data from then(1)) . So is there any way I can stop further execution in then(1) so that then(2) and catch() couldn't call ?
db.query('query......', [val1, val2])
.then(rslt => { return res.json({ mssg: "Email already exists!", error: "Email already exists!" }) })
.then(user => { return db.query('INSERT INTO ', value, (err, res, flds) => { err ? reject(err) : resolve(res) }) })
.then(user => { return res.json({ mssg: "Success", success: true}) })
.catch( (err) => { console.log(err) })
You can (and should) use an async function, instead of using the lower-level .then() API of the Promise object:
async function doTheThing() {
try {
const result = await db.query('...');
if (result) { // user exists
return res.json({...}); // this will end the entire function
}
const user = await db.query('...');
return res.json({...}); // success
} catch (err) {
console.log(err); // I don't recommend doing this. try/catch should be for recovery
}
}

Return json data from Function

I use a function for Fetch with below code :
var URL='...'
export function PostData(method,data){
fetch(URL+method,{
method:'POST',
body:JSON.stringify(data),
headers:{'Content-Type':'application/json'},
}).then(res => res.json())
.then(response => {
var ret=JSON.stringify(response)
return ret
})
.catch((error) => {
console.error(error)
})
}
and use it like below :
var retData=PostData('login/Authenticate',data)
retData is empty but in function ret has data
You PostData function does currently not return anything, so it is empty.
First step would be to add a return statement:
export function PostData(method,data){
return fetch(URL+method,{
method:'POST',
...
This will make your function return a value, but not just a simple value, but a promise! Promises are not the easiest to understand, but there is also a of people who tried to explain them
- https://developers.google.com/web/fundamentals/primers/promises
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Now how can you use the value anyway?
PostData('login/Authenticate',data)
.then(retData => {
// ... use retData here
});
Now, you used the react-native tag, so I am assuming you want to use this value in your render function. You can't do this simply by putting the PostData call in your render function. You'll have to put it in state, and then use that value in render:
state = { retData: null }
componentDidMount() {
PostData('login/Authenticate',data)
.then(retData => {
// This puts the data in the state after the request is done
this.setState({ retData: retData });
});
}
render() {
let retData = this.state.retData;
// ... use retData in your render here, will be `null` by default
There are a lot more different or cleaner ways to do this, but I tried to keep this answer as simple and bare as possible :)
It is empty at this point because the call to fetch is asynchronous and the literal is set to undefined as it moves to the next statement because it has not been resolved yet. One way around it is to return the promise object itself and then use .then to get the response once it is resolved.
var URL = '...'
export function PostData(method, data) {
// return the promise object
return fetch(URL + method, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
}).then(res => res.json())
.then(response => {
var ret = JSON.stringify(response)
return ret
})
.catch((error) => {
console.error(error)
})
}
PostData('login/Authenticate',data).then(response => {
// do something with the response
});
A cleaner approach would be is to use the async/await ES7 feature which makes it more readable.
var URL = '...'
export function PostData(method, data) {
// return the promise object
return fetch(URL + method, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
}).then(res => res.json())
.then(response => {
var ret = JSON.stringify(response)
return ret
})
.catch((error) => {
console.error(error)
})
}
async function getData() {
let retData = await PostData('login/Authenticate',data);
}

why promise.resolve lost value inside of async function?

I know when we use promise in JavaScript, we usally use two ways like below.
var f1 = () => {
return new Promise( (resolve, reject) => {
resolve(10);
})
}
var f2 = () => {
return Promise.resolve(10)
}
f1().then( data => { console.log(data) }) // 10
f2().then( data => { console.log(data) }) // 10
But if i use async function inside of promise, Promise.resolve lost the value like below.
const fs = require('fs')
var f1 = () => {
return new Promise( (resolve, reject) => {
fs.readFile('data.txt', (err, data) => {
resolve(data);
})
})
}
var f2 = () => {
return Promise.resolve()
.then(() => {
fs.readFile('data.txt', (err, data) => {
//return data --> undefined
//Promise.resolve(data) --> undefined
return Promise.resolve() --> undefined
})
})
}
f1().then( data => { console.log('1,',data) })
f2().then( data => { console.log('2,',data) })
I think that i use wrong way about Promise.resolve,,, OR Promise.resolve not support async function... someone tell me why Promose.resolve fail..
If you have a value that you immediately want to resolve a promise with, you can use Promise.resolve().
If you get the value asynchronously in a callback, you must use the new Promise constructor with the resolve/reject callbacks, there is no way around it.

(Serverless Framework Module) wait for promise to resolve before return statement

Is it possible for a Serverless Framework module to wait for the "resolve" of a promise before returning?
I'm aware that promises themselves can't do that, but different frameworks/libraries (express, Jasmine, hapijs, etc.) solve this by having a method that defines when to return. I need something like this:
let http = require('http'),
Promise = require('bluebird');
let action = (done) => {
return new Promise((resolve, reject) => {
http
.get('http://domain.com', resolve.bind({}, 'all good!'))
.on('error', reject.bind({}, 'all wrong!'));
})
.then((response) => {
console.log('Result', response);
return done(response); // <----------- I wan't to see this as the response
// of the lambda function
});
};
module.exports.run = (event, context, cb) => cb(null, action(done));
No, promises don't do that. It's impossible to read from the future, and don't want to (cannot) block. Your action is still asynchronous.
But given that your export takes a callback anyway, you can simply invoke that asynchronously:
module.exports.run = (event, context, cb) => {
action().then(res => cb(null, res), err=>cb(err));
};
It would be better though of course if you just returned the promise.