Reputation: 31365
I have the following function, which I want to re-use as an "action" template and pass another function as a parameter, which will be the action function, to be executed in the middle of it.
QUESTION
Is it possible? How can I do it?
Note that the "action" is asynchronous and also I'm using React.
function templateAction(action) {
try {
setLoading(true);
setError(null);
// DO SOMETHING
action();
setLoading(false);
}
catch(err) {
console.log(err);
setError(err);
setLoading(false);
}
}
And inside that action()
call should execute the following function:
async function getBlogPost() {
const querySnapshot = await firebase.firestore().collection('blog').where('slug','==',props.match.params.slug).get();
console.log(querySnapshot.docs);
if (querySnapshot.docs.length === 0) {
throw 'ERROR: BlogPost not found...';
} else if (querySnapshot.docs.length > 1) {
throw 'ERROR: More than 1 blogPost found...';
}
const blogPostData = querySnapshot.docs[0].data();
setFirestoreID(querySnapshot.docs[0].id);
setBlogPost(blogPostData);
}
SNIPPET
I think that I've built the behavior that I need (run snippet). Can I do it simpler than that? It seems a lot of boilerplate.
async function templateAction(action) {
try {
console.log('Template Action BEFORE calling action');
await action();
console.log('Template Action AFTER calling action');
}
catch(err) {
console.log(err);
}
}
function action() {
return new Promise(async (resolve,reject) => {
console.log('I am sync from action function BEFORE async call');
await mockAPI();
console.log('I am sync from action function AFTER async call');
resolve();
});
}
function mockAPI() {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log('I am from async mockAPI call');
resolve();
},1500);
});
}
templateAction(action);
Upvotes: 0
Views: 101
Reputation: 31365
Here is my final code, with error catching using try catch blocks.
It works, though I think it hurts readability.
async function templateAction(action) {
try {
console.log('Template Action BEFORE calling action');
await action();
console.log('Template Action AFTER calling action');
}
catch(err) {
console.log('I was caught and logged');
console.log(err);
}
}
function action() {
return new Promise(async (resolve,reject) => {
try {
console.log('I am sync from action function BEFORE async call');
await mockAPI();
console.log('I am sync from action function AFTER async call');
resolve();
}
catch(err) {
console.log('I was caught');
reject(err);
}
});
}
function mockAPI() {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log('I am from async mockAPI call');
resolve();
},1500);
});
}
templateAction(action);
Upvotes: 0
Reputation: 369
You can pass by anonymous function like this: https://codesandbox.io/embed/awesome-mayer-52ix7
function templateAction(action) {
action();
}
let test = function() {
alert("test");
};
templateAction(test);
For the async part, maybe you will need to make promise, depending if you need a confirmation for the action. With reactJS you can make this more simple by using scope sending properties and getting using "this.props"
Upvotes: 2