What I am trying to do here is painfully easy in other languages but I'm trying to understand Promises as I learn more about Node.js. I decided I'd do a quick loop over some data leftover from an old plugin in a WordPress database to create a report. This implementation isn't necessary as I could JOIN some of the data so please don't think less of me.
function suggestionGetComments(row) {
let commentsDiv = ''
return new Promise((resolve, reject) => {
sqlGet(`SELECT * FROM wp_comments WHERE comment_post_id = ${row.ID};`)
.then((result) => {
result.forEach(comment => {
commentsDiv += 'comments stuff'
})
})
.then(() => {
if (commentsDiv != '')
commentsDiv = '\t<ul class="suggestionComments">\n' + commentsDiv + '\t</ul>\n'
resolve(commentsDiv)
})
.catch((err) => {
console.error(err.message)
reject('*** Error with wp_comments ***')
})
})
}
function suggestionGetMeta(id) {
let userName, userEmail
return new Promise((resolve, reject) => {
sqlGet(`SELECT * FROM wp_postmeta WHERE post_id = ${id};`)
.then((result) => {
result.forEach(row => {
if (row.meta_key === '_avia_feedback_author')
userName = row.meta_value
else if (row.meta_key === '_avia_feedback_author_mail')
userEmail = row.meta_value
})
})
.then(() => {
if (userName && userEmail)
resolve(`${userName} (${userEmail})`)
else
resolve('*** MISSING DATA ***')
})
.catch((err) => {
console.error(err.message)
reject('*** Error with wp_postmeta ***')
})
})
}
function suggestionDisplay(row) {
let suggestionHTML = '<arcticle>\n'
return new Promise((resolve, reject) => {
const suggestionDate = new Date(Date.parse(row.post_date))
suggestionHTML += `\t<h2>${row.post_title}</h2>\n`
suggestionGetMeta(row.ID)
.then((result) => {
suggestionHTML += `\t<div class="suggestionBy">Suggested by ${result} on ${suggestionDate.toLocaleDateString()} ${suggestionDate.toLocaleTimeString()}</div>\n`
suggestionHTML += `\t<div class="suggestionContent">${row.post_content}</div>\n`
})
.then(suggestionGetComments(row))
.then((result) => {
suggestionHTML += result
suggestionHTML += '</article>\n'
console.log(suggestionHTML)
resolve('Suggestion Displayed')
})
.catch((err) => {
console.error(err.message)
reject(new Error('Failed to get Meta'))
})
})
}
function sqlGet(sqlText) {
return new Promise(function(resolve, reject) {
con.query(sqlText, function(err, rows, fields) {
if (err) {
return reject(err)
}
return resolve(rows)
})
})
}
The primary function suggestionDisplay works except for the call to suggestionGetComments which adds "undefined" to the string as you can see in this edited example of the output:
<arcticle>
<h2>Some Suggestion</h2>
<div class="suggestionBy">Suggested by someonene (some email) on 11/5/2012 3:05:50 AM</div>
<div class="suggestionContent">The reason for the suggestion</div>
undefined</article>
Bottom line I have a Promise function suggestionDisplay which needs to call 2 other Promise functions suggestionGetMeta and suggestionGetComments both of which return values I need to process. The first works great. The second function works but I can't seem to figure out how to work with its results.