Skip to main content

convert callback to async/await with promise

1) Node version 8 and above now support turning callback functions into promises using the built-in util module.

const request = require('request');

const util = require('util');

const fetchData = util.promisify(request);

fetchData(url).then(data => {

   let content = JSON.parse(data.body);
   
   console.log('Joke: ', content.value);
   
}).catch(err => console.log('error: ', err))
2) Turn callback into a promise


export const mergePdfs = async (pdf1: string, pdf2: string, pdf: string) => {
  return new Promise((resolve, reject) => {
    merge([pdf1, pdf2], pdf, (error: any) => {
      if (error) {
        return reject(error)
      }
      resolve('')
    })
  })
}

3) sample for printPDF
export const printPdf = (
userId: string,
listingId: string,
listingForm: ListingForm,
listingData: any,
signatures: string[] //SignatureWithDate[]
): Promise<string> => {
return new Promise(async (resolve, reject) => {
const localDate = formatTimestamp(new Date().toLocaleString())
try {
let signature: Buffer
let signature2: Buffer
let signatureBuffers: Buffer[] = []
if (signatures.length > 0) {
signature = await axios
.get(signatures[0], {
responseType: 'arraybuffer',
})
.then(response => Buffer.from(response.data, 'binary'))
//signatureDate = localDate //signatures[0].created
signatureBuffers.push(signature)
if (signatures.length > 1) {
signature2 = await axios
.get(signatures[1], {
responseType: 'arraybuffer',
})
.then(response => Buffer.from(response.data, 'binary'))
//signature2Date = localDate //signatures[1].created
signatureBuffers.push(signature2)
signatureBuffers.push(signature2)
}
}
const doc = new PDFDocument()
const timestamp = Number(new Date())
const fileName = `${userId}-${listingId}-${timestamp.toString()}.pdf`
const { postalCode, city, stateCode, addressLine1 } = listingData
const {
listingFormData: { fields },
description,
} = listingForm
const writeStream = fs.createWriteStream(fileName)
doc.pipe(writeStream)
doc.image('logo.jpg', 0, 0, { width: 220, height: 45 })
doc.fontSize(25).text(description, 100, 100)
doc.fontSize(25).text(`${addressLine1} ${city} ${stateCode} ${postalCode}`, 100, 300)
fields.map((field: any) => {
doc
//.addPage({ margins: { top: 50, bottom: 100, left: 72, right: 72 } })
.addPage()
.fontSize(25)
.text(field.title, 100, 100)
doc.moveDown()
const contentWidth = doc.page.width - doc.page.margins.left - doc.page.margins.right
let cols = 0
let nextLeft = doc.page.margins.left
let havingFieldSetOfLastOption = false
field.options.map((option: any) => {
if (
doc.y >=
doc.page.height - doc.page.margins.bottom - signatureMargin - heightOfSignatureArea
) {
addSignatures(doc, signatureBuffers, localDate)
doc.addPage()
}
const gridColumns = option.gridColumns['lg']
if (gridColumns === 12 || cols >= 12 || havingFieldSetOfLastOption) {
if ((gridColumns === 12 && cols < 12) || havingFieldSetOfLastOption) {
doc.moveDown()
doc.moveDown()
}
cols = 0
nextLeft = doc.page.margins.left
doc.moveDown()
}
doc.fillColor('#999999').fontSize(10).text(`${option.title}`, nextLeft)
if (option.type !== 'fieldset') {
let fieldValue
try {
fieldValue = listingData.data[option.key]
} catch (error) {
fieldValue = 'N/A'
}
doc.fillColor('#000000').fontSize(10).text(` ${fieldValue} `, nextLeft)
}
switch (gridColumns) {
case 9:
nextLeft += (contentWidth * 1.5) / 2
cols += 9
break
case 6:
nextLeft += contentWidth / 2
cols += 6
break
case 3:
nextLeft += contentWidth / 4
cols += 3
break
default:
break
}
if (cols < 12 && cols > 0) {
doc.moveUp()
doc.moveUp()
}
if (option.type === 'fieldset') {
havingFieldSetOfLastOption = true
let index = 0
option.options &&
option.options.map((o: any) => {
const leftFs = doc.page.margins.left + ((index % 4) * contentWidth) / 4
let fieldSetValue
try {
fieldSetValue = listingData.data[option.key][o.key]
} catch (error) {
fieldSetValue = 'N/A'
}
if (
doc.y >=
doc.page.height -
doc.page.margins.bottom -
heightOfSignatureArea -
signatureMargin
) {
addSignatures(doc, signatureBuffers, localDate)
doc.addPage()
}
if (fieldSetValue.toString() === 'true')
doc.image('check-true.jpg', leftFs, doc.y, { width: 10, height: 10 })
else doc.image('check-false.jpg', leftFs, doc.y, { width: 10, height: 10 })
doc.moveUp()
doc
.fillColor('#0866a1')
.fontSize(10)
.text(`${o.title} `, leftFs + 12, doc.y + 2)
if (o.title.length > 21 && index % 4 !== 3) index += 1
doc.fillColor('#000000').fontSize(10).text(` `, leftFs)
if (index !== 0 && index % 4 === 3) {
doc.moveDown()
} else {
doc.moveUp()
doc.moveUp()
}
index += 1
})
} else {
havingFieldSetOfLastOption = false
}
})
addSignatures(doc, signatureBuffers, localDate)
})
doc.end()
return writeStream.on('finish', () => {
resolve(fileName)
})
} catch (error) {
reject(error)
}
})
}
const addSignatures = (doc: any, signatures: any[], signatureDate: string) => {
const sigTop = doc.page.height - doc.page.margins.bottom - heightOfSignatureArea
const sigDateTop = sigTop + 50
const contentWidth = doc.page.width - doc.page.margins.left - doc.page.margins.right
signatures.forEach((signature, idx) => {
const left = Math.floor((contentWidth * idx) / 3) + doc.page.margins.left
doc
.image(signature, left, sigTop + 15, {
width: contentWidth / 3,
})
.text(idx < 2 ? 'Seller' : 'Broker', left, sigTop)
doc.fontSize(10).text(signatureDate, left, sigDateTop)
})
}
let fileName
try {
fileName = await printPdf(uid, listingId, listingForm, listingData, signatureUrls)
} catch (error) {
throw new ApolloError(error, 'Print PDF error')
}
view raw gistfile1.txt hosted with ❤ by GitHub

Comments

Popular posts from this blog

for loop in javascript - promise - .eslintrc for "for of"

the vast majority of cases  map ,  forEach ,  find  etc. can be used.  async function printFiles () { const files = await getFilePaths(); await Promise.all(files. map (async (file) => { const contents = await fs.readFile(file, 'utf8') console.log(contents) })); } const inventory = [ { name : 'apples' , quantity : 2 } , { name : 'bananas' , quantity : 0 } , { name : 'cherries' , quantity : 5 } ] ; const result = inventory . find ( ( { name } ) => name === 'cherries' ) ;   function getFirstMatching(array) { for (let item of array) { const result = heavyTransform(item); if (result) { return result; } } } Specifically this shuts down the whole no-restricted-syntax. If you want to cherry-pick, here is the current definition: 'no-restricted-syntax' : [ 'error' , { selector : 'ForInStatement' , message...

Apollo client - cache APIs - auto update cache - erase cache - reactive variables - deletion - addition

Apollo Client 3  Local only fields Reactive Variables const cache = new InMemoryCache ( { typePolicies : { Todo : { // If one of the keyFields is an object with fields of its own, you can // include those nested keyFields by using a nested array of strings: keyFields : [ "date" , "user" , [ "email" ] ] , } } , } ) ; This internal data is intended to be easily  JSON-serializable , so you can take a snapshot with  cache.extract() , save it somewhere, and later restore with  cache.restore(snapshot) . Here’s a mutation called  EditTodo  that returns the new  todo  value in the mutation response. mutation EditTodo ( $id : Int ! , $text : String ! ) { editTodo ( id : $id , text : $text ) { success todo { # <- Returning it here id text completed } error { ... on TodoNotFoundError { message } ... on TodoValidationE...

window.URL.createObjectURL is not (yet) available in jest-dom - testing scenario

Since  window.URL.createObjectURL  is not (yet) available in jest-dom, you need to provide a mock implementation for it. Don't forget to reset the mock implementation after each test. describe ( "your test suite" , () => { window . URL . createObjectURL = jest . fn (); afterEach (() => { window . URL . createObjectURL . mockReset (); }); it ( "your test case" , () => { expect ( true ). toBeTruthy (); }); });