How to return resolve() if all the fields is valid otherwise return reject?
let validateData = (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
return new Promise((resolve, reject) => {
fields.forEach(field => {
if (data.hasOwnProperty(field)) {
// resolve if all matched
} else {
//reject?
}
});
});
}
In the main it will have
try {
await validateData(data);
} catch(err) {
throw new Error(`${err}`);
}
If any of the fields do not exist on the data object reject as soon as it is found out. If not you can resolve in the end.
let validateData = (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
return new Promise((resolve, reject) => {
fields.forEach(field => {
if (!data.hasOwnProperty(field)) {
reject();
}
});
resolve();
});
}
return new Promise((resolve, reject) => {
fields.forEach(field => {
if (!data.hasOwnProperty(field)) {
reject();
return;
}
});
resolve();
});
If any of the properties is not valid simply reject else if all of them are valid it wont go inside the if statement and it will resolve the promise.
The error object will contain a description of the validation errors:
let validateData = (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
return new Promise((resolve, reject) => {
let errors = [];
fields.forEach(field => {
if (!data.hasOwnProperty(field)) {
errors.push(`ValidationFieldError: ${field}`);
}
});
errors.length ? reject(new Error(errors.join('\n'))) : resolve();
});
}
If all fields validaton require async operation, you can use Promise.all, which will be resolved only if all the fields validation have been resolved.
E.g.
let validateData = async (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
let fieldsValidatedPromsises = [];
fields.forEach(field => {
let validationPromise = new Promise( function (resolve, reject) {
if (data.hasOwnProperty(field)) {
// resolve if all matched
} else {
//reject?
}
});
fieldsValidatedPromsises.push(validationPromise);
});
return Promise.all(fieldsValidatedPromsises).then(function () {
return true;
})
.catch(function () {
return false;
});
}
let c = await validateData(data);
if (c) {
// All fields validation is successful
}
else {
// One of field validation fails
}
An elegant way would be
let validateData = async (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
let promises = [];
fields.forEach(field =>
promises.push(new Promise((resolve) =>
data.hasOwnProperty(field) ? resolve() : reject())
)
);
return Promise.all(promises);
}
Demo
let validateData = async(data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
let promises = [];
fields.forEach(field =>
promises.push(new Promise((resolve) =>
data.hasOwnProperty(field) ? resolve() : reject()))
);
return Promise.all(promises);
}
async function foo() {
try {
await validateData({
'Field1': 1,
'Field2': 2,
'Field3': 3
});
console.log('valid here');
} catch (err) {
console.log('Invalid');
}
}
foo();
Yet another approach...
let validateData = (data) => {
let fields = [
'Field1',
'Field2',
'Field3'
];
return new Promise((resolve, reject) => {
fields.every(field => data.includes(field)) ? resolve() : reject();
});
}
Related
As you can see in the code below that while typing or searching, the user also searches the data in the database for what the user is typing.
const searchData = useState();
const fetchSearchPerson = async (name) => {
const { data } = await client.query({
query: SEARCH_PERSON,
variables: {
name: name
},
})
searchData = new Promise((resolve, reject) => {
setTimeout(() => {
resolve (data);
}, 1000);
});
return data;
};
.....
fetchSearchPerson(params.suggestTerm)
return searchData.map((data) => {
console.log("datas: ", data)
});
.....
Error I have encountered so far:
UPDATE
const [searchData, setSearchData] = useState();
const fetchSearchPerson = async (name) => {
const { data } = await client.query({
query: SEARCH_PEOPLE,
variables: {
name: name,
},
})
const searchDataPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve (data);
}, 1000);
});
setSearchData(searchDataPromise); // add this
return data;
};
fetchSearchPerson(params.suggestTerm)
return searchData.map((data) => {
console.log("datas: ", data)
})
I dont received the error but the result from the search data
In c# I would write something like this:
bool HasRole(string userName, string[] groupNames)
{
var ad = new ActiveDirectory();
return groupsNames.Any(groupName => ad.IsUserInGroup(userName, groupName);
}
and then just
if (HasRole("UserName", new[] {"group1", "group2"}))
//do something
in javascript it looks like all things are doing asynchronously, I've read about promises and so on, and tried this:
const ActiveDirectory = require('activedirectory2');
const Promise = require('promise');
const globals = require('./globals');
const activeDirectory = new ActiveDirectory(globals.AdConfig);
hasRole(msg, ...groupNames) {
if (groupNames == null || groupNames == undefined || groupNames.length == 0)
return false;
let promises = [];
groupNames.forEach(groupName => {
let promise = new Promise((resolve, reject) => {
activeDirectory.isUserMemberOf(msg.envelope.user.name, groupName, function (err, isMember) {
if (err) {
reject(err)
}
resolve(isMember);
});
});
promises.push(promise);
});
//I don't clearly understand how I can return promise result only or promise with the right result
let hasRole = false;
promises.forEach(promise => promise.done(result => {
if (result)
hasRole = result;
}));
return hasRole;
So how can write something like:
if (hasRole(msg, 'group1', 'group2'))
//do something...
I suppose I should return promise but how I can do it if i need to check multiple groups?
UPDATE
I wrapped the forEach loop in promise:
return new Promise((resolve, reject) => {
promises.forEach(promise => promise.done(result => {
if (result)
return resolve(result);
}));
and then:
hasRole(msg, 'group1', 'group2').done(result => {
if (result)
//do...
});
May there is another way?
Found a solution. Promises.all is what i needed.
Result code:
hasRole(msg, ...groupNames) {
let promises = [];
groupNames = groupNames.filter(x => x.trim().length > 0);
if (groupNames == undefined || groupNames.length == 0)
{
promises.push(new Promise.resolve(false));
return Promise.all(promises);
}
groupNames.forEach(groupName => {
let promise = new Promise((resolve, reject) => {
activeDirectory.isUserMemberOf(msg.envelope.user.name, groupName, function (err, isMember) {
if (err) {
reject(err)
}
resolve(isMember);
});
});
promises.push(promise);
});
return Promise.all(promises);
}
This is my first post so sorry if I have done it wrong.
I am trying to chain javascript promises together but when I run it I get the error Uncaught TypeError: Cannot read property 'then' of undefined
at script.js:108
(anonymous) # script.js:108
Do you know what i am doing wrong?
const crates = {
clothes: 8,
hats: 20,
toys: 50,
}
const orderToys = () => {
new Promise((resolve, reject) => {
if (crates.toys < 60){
resolve('yes');
} else {
reject('no');
}
})
}
const sendMoney = (val) => {
new Promise((resolve, reject) => {
if(val === 'yes'){
resolve('money sent');
} else {
reject('no order needed, do not sent money');
}
})
}
const orderConfirmed = (val) =>{
new Promise((resolve, reject) => {
if(val ==='money sent'){
resolve('shipped');
} else {
reject('No money sent');
}
})
}
const delivered = (val) =>{
new Promise((resolve, reject) => {
if(val === 'shipped'){
resolve('order completed');
} else {
reject('no order');
}
})
};
orderToys()
.then((firstVal) => {
return sendMoney(firstval);
})
.then((secondVal) =>{
return orderConfirmed(secondVal);
})
.then((thirdVal) =>{
return delivered(thirdVal);
})
.then((fourthVal) =>{
console.log(fourthVal);
})
Either return the promise:
const orderToys = () => {
return new Promise((resolve, reject) => {
if (crates.toys < 60) {
resolve('yes');
} else {
reject('no');
}
})
}
or use the expression form of the arrow function.
const orderToys = () =>
new Promise((resolve, reject) => {
if (crates.toys < 60) {
resolve('yes');
} else {
reject('no');
}
});
You are not returning the promises from the function. You need to return the promise before you try to resolve them. Hope this helps.
const crates = {
clothes: 8,
hats: 20,
toys: 50,
}
const orderToys = () => {
return new Promise((resolve, reject) => {
if (crates.toys < 60){
resolve('yes');
} else {
reject('no');
}
})
}
const sendMoney = (val) => {
return new Promise((resolve, reject) => {
if(val === 'yes'){
resolve('money sent');
} else {
reject('no order needed, do not sent money');
}
})
}
const orderConfirmed = (val) =>{
return new Promise((resolve, reject) => {
if(val ==='money sent'){
resolve('shipped');
} else {
reject('No money sent');
}
})
}
const delivered = (val) =>{
return new Promise((resolve, reject) => {
if(val === 'shipped'){
resolve('order completed');
} else {
reject('no order');
}
})
};
orderToys()
.then((firstVal) => {
return sendMoney(firstVal);
})
.then((secondVal) =>{
return orderConfirmed(secondVal);
})
.then((thirdVal) =>{
return delivered(thirdVal);
})
.then((fourthVal) =>{
console.log(fourthVal);
})
If you are using Promises then you must return the promise as well in order to preserve the promise chain:
const crates = {
clothes: 8,
hats: 20,
toys: 50,
};
const orderToys = () => {
return new Promise((resolve, reject) => {
if (crates.toys < 60) {
resolve('yes');
} else {
reject('no');
}
});
};
const sendMoney = (val) => {
return new Promise((resolve, reject) => {
if (val === 'yes') {
resolve('money sent');
} else {
reject('no order needed, do not sent money');
}
});
};
const orderConfirmed = (val) => {
return new Promise((resolve, reject) => {
if (val === 'money sent') {
resolve('shipped');
} else {
reject('No money sent');
}
});
};
const delivered = (val) => {
return new Promise((resolve, reject) => {
if (val === 'shipped') {
resolve('order completed');
} else {
reject('no order');
}
});
};
Usage:
orderToys()
.then((firstVal) => {
return sendMoney(firstval);
})
.then((secondVal) => {
return orderConfirmed(secondVal);
})
.then((thirdVal) => {
return delivered(thirdVal);
})
.then((fourthVal) => {
console.log(fourthVal);
});
Or if you need to use async-await form:
(async function () {
try {
const value1 = await orderToys();
const value2 = await sendMoney(value1);
const value3 = await orderConfirmed(value2);
await delivered(value3);
} catch (e) {
// Handle errors
console.log(e);
}
})();
I have a class method (for 'apollo-datasource-rest' that is supposed to fetch a plan from a plan_id. I need to hit two endpoints and combine the data. This works with Promise.all([promise1, promise2]) and then passes the user_ids on to the next Promise.all method that calls the GET /users endpoint multiple times. If I console.log out the usersArray that is returned, I get the array of users, but if I try to return that array, it doesn't get assigned to the objToReturn variable. I also need to add data from snapshot2 to the objToReturn but that is secondary.
getPlanById = async ( planId ) => {
const promise1 = new Promise((resolve) => {
return resolve(this.get('/url1'))
});
const promise2 = new Promise((resolve) => {
return resolve(this.get('/url2'))
});
const objToReturn = await Promise.all([promise1, promise2])
.then(([snapshot1, snapshot2]) => {
return snapshot1.user_ids
})
.then((userIds) => {
this.getUsersFromUserIds(userIds).then((usersArray) => {
console.log(usersArray)
// return usersArray doesn't assign to objToReturn
})
})
return objToReturn
}
getUsersFromUserIds(userIds) {
let userPromises = []
userIds.forEach((uid) => {
const promise = this.get(`/users/${uid}`)
.then((response) => {
if (response.status === 'success') {
return response.data.user
} else {
return null
}
})
userPromises.push(promise)
})
return Promise.all(userPromises).
then((userPromiseData) => {
return userPromiseData
})
}
You need to return the promise of this.getUsersFromUserIds(userIds). So that the promise chain can work.
E.g.
index.js:
class UserAPI {
async getPlanById(planId) {
const promise1 = Promise.resolve({ user_ids: [1, 2] });
const promise2 = Promise.resolve();
const objToReturn = await Promise.all([promise1, promise2])
.then(([snapshot1, snapshot2]) => {
return snapshot1.user_ids;
})
.then((userIds) => {
// You need to return here
return this.getUsersFromUserIds(userIds).then((usersArray) => {
return usersArray;
});
});
return objToReturn;
}
async getUsersFromUserIds(userIds) {
return [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
];
}
}
const userAPI = new UserAPI();
userAPI.getPlanById(1).then((objToReturn) => {
console.log('objToReturn: ', objToReturn);
});
The output in the console:
objToReturn: [ { id: 1, name: 'a' }, { id: 2, name: 'b' } ]
The last line of code doesn't work and I don't know how to fix it. I understand that second "then" has to return resolve() but how can I realize it?
let getNumber = new Promise((resolve) => {
//API
EthereumNote.getAmountOfMyNotes(function(error, result) {
if (!error) {
let AmountOfMyNotes = Number(result)
resolve(AmountOfMyNotes)
console.log(result)
} else
console.error(error)
})
}).then(result => {
return new Promise((resolve) => {
for (let i = 0, p = Promise.resolve(); i < result; i++) {
p = p.then(_ => new Promise(resolve => {
//API
EthereumNote.getMyNote(i, function(error, result) {
if (!error) {
let text = String(result[0])
let noteID = Number(result[1])
console.log(text)
console.log(noteID)
resolve()
} else
console.error(error)
})
}));
}
})
}).then(() => console.log('Hi!')) // this one doesn't work
Avoid the Promise constructor antipattern! It's ok to make a new Promise to wrap EthereumNote.getMyNote, it's not ok to wrap the loop. You never resolve() that outer promise.
Instead, just return the promise chain you created in p:
let getNumber = new Promise((resolve) => {
//API
EthereumNote.getAmountOfMyNotes(function(error, result) {
if (error) reject(error);
else resolve(Number(result));
})
}).then(amountOfMyNotes => {
console.log(amountOfMyNotes);
var p = Promise.resolve();
for (let i = 0; i < amountOfMyNotes; i++) {
p = p.then(_ => new Promise((resolve, reject) => {
//API
EthereumNote.getMyNote(i, function(error, result) {
if (error) reject(error);
else resolve(result);
});
})).then(result => {
let text = String(result[0])
let noteID = Number(result[1])
console.log(text)
console.log(noteID))
});
}
return p;
}).then(() => {
console.log('Hi!'); // this one now works
}, err => {
console.error(err);
});