How can I do this with chai-as-promised:
Currently I am using chai expect:
return User.auth(data).then(function(usr){
expect(usr).to.have.property('user', 'alvin');
expect(usr).to.have.property('email', 'alvin#l.com');
});
for chai-as-promisied, I can call mulutiple call but I would like to call once:
return User.auth(data).should.eventually.have.property('');
return User.auth(data).should.eventually.have.property('');
The solution:
it('should return user', function(){
this.timeout(15000);
let data = { req: {
email: 'alvin#l.com'
}};
let expected = {
email: 'alvin#l.com'
};
return
User.auth(data).should.be.fulfilled.and.eventually.include(expected);
});
Related
I have an async function that uses redux and it calls an API and returns the response from the server:
function xyz() {
return async (dispatch, getState) => {
const { user: { token } } = getState();
return axios.get(API_URL, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
'jwt': token
}
})
.then(response => {
console.log(response.data.data);
return response.data.data;
})
.catch(function(error) {
console.log('error: ' + error.message);
});
};
}
The mapDispatchToProps function is defined as it follows:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
xyz: () => {
dispatch(actions.xyz());
}
};
};
export default connect(null, mapDispatchToProps)(Container);
I'm trying to call the function xyz from the following function:
abc = async () => {
const { xyz } = this.props;
const result = await xyz();
console.log(result);
}
which is triggered when a button is pressed:
<TouchableOpacity onPressOut={this.abc}>
I see that the console.log into the function abc prints undefined, while the console.log(result.data.data) into xyz prints the expected result. Where am I wrong?
Solution
The error was in the mapDispatchToProps function, which was missing the return. Here it is the correct implementation:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
xyz: () => {
return dispatch(actions.xyz());
}
};
};
export default connect(null, mapDispatchToProps)(Container);
Like I mentioned in the comments, xyz() should return a promise. Double check that the dispatch and getState arguments are getting passed correctly. You'll also need to await the returned axios.get promise. For example:
abc = async () => {
const { xyz } = this.props;
const result = await xyz();
const results = await result();
console.log(results);
}
Here is a snack with a working example.
I don't fully understand what you mean when you say the console.log in xyz prints the expected result, are you speaking about the error.message in your catch? Also, the reason you may be receiving undefined is because function xyz is not Async but rather it returns an async function, thus you should make xyz async such as:
function async xyz () {
// Rest of code
}
For more you can read here
Am using Vue Validate
i have the following in my vuevlidate
validations: {
user_form: {
email: {required,email, isUnique(value) {
// standalone validator ideally should not assume a field is required
if (value === '') return true;
// simulate async call, fail for all logins with even length
return new Promise((resolve, reject) => {
this.$http.post("v1/user-management/users/email-registeredi",{email:value}).then((res)=>{
console.log("res is ", res);
resolve(true);
},(err)=>{
reject(false)
})
})
}},
role: {required},
password: {required}
}
},
The above creates an endless loop of http requests especially when it gets an error
Where am i going wrong
In case vue validate is not handling reject promise well and creating infinite loop.
You can try, async await for Vue validate's isUnique with try and catch returning false on error,
something like this.
validations: {
user_form: {
email: {
required,
email,
async isUnique (value) {
if (value === '') return true
try{
const response = await this.$http.post("v1/user-management/users/email-registeredi",{email:value})
return true;
}
catch(e){
return false;
}
}
}
}
You don't need to use "new Promise" because vue-resource already do that. Try this:
validations: {
user_form: {
email: {required,email, isUnique(value) {
// standalone validator ideally should not assume a field is required
if (value === '') return true;
// simulate async call, fail for all logins with even length
return this.$http.post("v1/user-management/users/email-registeredi",{email:value}).then((res)=>{
console.log("res is ", res);
return true;
},(err)=>{
return false;
});
}},
role: {required},
password: {required}
}
},
I created a function called getAllCams in my ApiServices.js page.
async getAllCams() {
try {
const getAlarmListRes = await
fetch(`someurl`,
{
method: 'GET',
headers: new Headers({
Authorization: `Basic ${base64.encode('user-id:1234')}`,
'Content-Type': 'application/json'
})
});
if (getAlarmListRes.status === 200) {
const newData = await getAlarmListRes.json();
if (newData !== '') {
loggingService.debug('here is your array', newData.alarms);
return newData;
}
return ApiService.FAILURE;
}
loggingService.debug('Was not able to get alarm list for you', getAlarmListRes);
return ApiService.FAILURE;
} catch (e) {
loggingService.debug('could not get alarm list', e);
}
}
when I call this function on CameraNotification.js page
componentWillMount() {
loggingService.debug('component did mount');
const listOfCams = apiService.getAllCams();
loggingService.debug('here is your promise object', listOfCams);
}
I keep getting the result of the first await, which is simple a promise object that I convert to a JSON object in the second await. From my understanding of await, listOfCams should return an array, not the promise object. What is causing this to happen? I've tried writing the code with .then() and the same thing happens.
While converting legacy long sql procedure to sequelizer, I met trouble to make transaction to my async functions.
I read sequelizer's transaction documents. But failed to understand clearly.
Here is my code.
const models = require('../models/models.js');
const sequelize = models.Sequelize;
async function isExistFeeHist(dansokSeqNo) {
log.debug("isExistFeeHist()");
let feeHist = await models.FeeHist.findOne({
where: {
DansokSeqNo: dansokSeqNo,
FeeStatus: {[Op.ne]: null}, //is not null
DelYN: false
}
});
return !!feeHist;
}
async function isPaid(dansokSeqNo) {
...
}
async function getNextDansokHistSerialNo(dansokSeqNo) {
...
}
async function getVBankSeqNo(dansokSeqNo) {
...
}
async function updateVBankList(dansokSeqNo, vBankSeqNo) {
...
}
//check if can cancel
async function checkCancelable(dansokSeqNo) {
log.debug("checkCancelable() ", dansokSeqNo);
if (await isExistFeeHist(dansokSeqNo)) {
let e = {status:400, message: 'already imposed dansokSeqNo ' + dansokSeqNo };
return Promise.reject({status:400, message: e.message });
}
if (await isPaid(dansokSeqNo)) {
let e = {status:400, message: 'already paid dansokSeqNo ' + dansokSeqNo };
return Promise.reject({status:400, message: e.message });
}
return Promise.resolve();
}
....
async function doCancel(dansokSeqNo, cancelCauseCode, histMemo) {
try {
await checkCancelable(dansokSeqNo);
//// <== Here I want to start transaction
let nextDansokSerialNo = await getNextDansokHistSerialNo(dansokSeqNo);
let dansokHist = await insertNewDansokHist(dansokSeqNo, nextDansokSerialNo, cancelCauseCode, histMemo);
await updateDansokHist(dansokSeqNo, cancelCauseCode);
let vBankSeqNo = await getVBankSeqNo(dansokSeqNo);
if (vBankSeqNo > 0) {
await updateVBankList(dansokSeqNo, vBankSeqNo);
let vBankList = await getVBankList(dansokSeqNo);
}
// <== Here I want to commit transaction
} catch (e) {
// <== Here I want to rollback transaction
return Promise.reject({status:e.status, message: e.message });
}
}
exports.cancelDansok = function (req, res) {
res.setHeader("Content-Type", "application/json; charset=utf-8");
...
jwtAcessAuth(accessToken)
.then((decoded) => {
log.info("jwt success, ", decoded);
worker = decoded.loginName;
return doCancel(dansokSeqNo, cancelCauseCode, histMemo);
})
.then(() => {
res.status(200).json({ message: 'cancelDansok success.' });
})
.catch(e => {
return res.status(e.status).json(e);
});
};
My function is assembled with several async functions. And it need to bind one transaction.
What is the best practice to use transaction in my several async await functions?
Here is the best example provided by Sequlize for Transaction :
All you need to care is pass transaction to next level of chaining
return sequelize.transaction(function (t) {
// chain all your queries here. make sure you return them.
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, {transaction: t}).then(function (user) {
return user.setShooter({
firstName: 'John',
lastName: 'Boothe'
}, {transaction: t});
});
}).then(function (result) {
// Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback
}).catch(function (err) {
// Transaction has been rolled back
// err is whatever rejected the promise chain returned to the transaction callback
});
For more details : Transactions
Can I make a custom validation rule that returns true/false based on a AJAX request? the problem is that the validate call has finished running when the AJAX call completes.
Do I need to have the rule set/unset a boolean variable based on which the field is valid/invalid?
const isValidNameRule = {
getMessage(field)
{
return "The name must be unique."
},
validate(validatingName)
{
var formData = new FormData();
formData.append("validatingName", validatingName);
this.$http.post("/api/isValid?name=" + validatingName, formData)
.then(function (response) {
// success
return true;
}, function (response) {
// error
return false;
});
}
};
Didn't know how to work with Promises.
Eventually got it working by extending one of the official samples:
const customRule = {
getMessage(field, params, data) {
return (data && data.message) || 'Something went wrong';
},
validate(aValue) {
return new Promise(resolve => {
var formData = new FormData();
formData.append("nameFilter", aValue);
$.ajax({
type: "POST",
url: url,
data: {
action: "validate",
value: aValue,
}
}).done(function (data) {
if (!ok)
{
resolve({
valid: false,
data: {message: "Condition not met"}
});
}
else
{
resolve({
valid: !! aValue,
data: undefined
});
}
});
});
}
};