Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

Build a Node.js PDF Invoice Document Generator in Express.js Using HTML5 Template in Javascript

Posted on October 25, 2022

Welcome folks today in this blog post we will be generating the pdf invoice document generator using the html5 template in javascript. All the full source code of the application is shown below.

 

 

 

 

Get Started

 

 

In order to get started you need to initialize a new node.js project using the below command as shown below

 

 

npm init -y

 

 

npm i express

 

 

npm i dotenv

 

 

npm i convert-html-to-pdf

 

 

As you can see that we are installing the above dependencies to convert the html5 template to pdf invoice document.

 

 

Now we need to make the index.js file which will be the starting point of the application as shown below

 

 

index.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const express = require("express")
const app = express()
app.use(express.json())
const PORT = 11000
 
const deliveryOptions = {
    logo: "https://thumbs.dreamstime.com/b/laundry-basket-icon-trendy-design-style-isolated-white-background-vector-simple-modern-flat-symbol-web-site-mobile-135748439.jpg",
    name: "Company Name",
    address1: "Some Road No 1",
    address2: "Some State, Pincode",
    orderId: "INV-001",
    customerName: "Sai Sandeep",
    date: "Oct 2, 2022",
    paymentTerms: "Delivery Items Receipt",
    items: [
        {
            name: "SINGLE BED_SHEET",
            qty: 3,
            rate: "10.00",
            amount: "30.00"
        },
        {
            name: "DOUBLE BED_SHEET",
            qty: 2,
            rate: "20.00",
            amount: "40.00"
        },
        {
            name: "TOWELS",
            qty: 3,
            rate: "5.00",
            amount: "15.00"
        },
        {
            name: "CLOTHES",
            qty: 3,
            rate: "50.00",
            amount: "150.00"
        }
    ],
    total: "235.00",
    balanceDue: "235.00",
    notes: "Thanks for being an awesome customer!",
    terms: "This invoice is auto generated at the time of delivery. If there is any issue, Contact provider"
}
 
app.get("/", (req,res)=> {
    res.status(200).send({msg: "Hi there, welcome to Invoice API. Go to /sample route to get sample data"})
})
 
app.get("/sample", (req,res) => {
    res.status(200).send(deliveryOptions)
})
 
 
app.listen(PORT, () => {
    console.log(`Listening on PORT ${PORT}`)
})

 

 

As you can see we are starting out the express app at the port number 11000. And then we are starting this app at that port number.

 

And also we have the / route. Inside that we are returning the sample json data where we will be returning the basic message to the user with the instructions on how to use this api.

 

And also we have the second /sample route where we are sending the json response where we are sending the delivery options. Inside the delivery options we have the sample json data in which we have the different information which will be used to create the invoice pdf document. It contains the details about the user and the products.

 

 

Making the POST Request to Generate the PDF Invoice

 

 

And now we will be defining the post request to generate the pdf invoice document and download it inside the local disk.

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
app.post("/getInvoice", (req,res) => {
    const result = verifyBody(req.body)
    if(result.success){
        getInvoice(req.body).then(pdf => {
            res.status(200)
            res.contentType("application/pdf");
            res.send(pdf);
        }).catch(err => {
            console.error(err)
            res.status(500).send({success: false, error: "something went wrong"})
        })
    } else {
        res.status(400).send(result)
    }
 
})

 

 

And now as you can see we have the post request inside that we are first of all getting the request payload data which is sent from the client side to this post request. And first of all we are writing a custom function which is used to validate the request data object which is coming from the client to the server.

 

 

Creating the Validating Function to Verify the Request Data

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
function verifyBody(data){
    if(!data?.logo){
        return {
            success: false,
            msg: "logo is missing"
        }
    }
 
    if(!data?.name){
        return {
            success: false,
            msg: "name is missing"
        }
    }
 
    if(!data?.address1){
        return {
            success: false,
            msg: "address1 is missing"
        }
    }
 
    if(!data?.address2){
        return {
            success: false,
            msg: "address2 is missing"
        }
    }
 
    if(!data?.orderId){
        return {
            success: false,
            msg: "orderId is missing"
        }
    }
 
    if(!data?.customerName){
        return {
            success: false,
            msg: "customerName is missing"
        }
    }
 
    if(!data?.paymentTerms){
        return {
            success: false,
            msg: "paymentTerms is missing"
        }
    }
 
    if(!data?.date){
        return {
            success: false,
            msg: "date is missing"
        }
    }
 
    if(!data?.items){
        return {
            success: false,
            msg: "items is missing"
        }
    }
 
    for(let i = 0; i < data.items.length; i++){
        if(!data.items[i]?.name){
            return {
                success: false,
                msg: `items.${i}.name is missing`
            }
        }
 
        if(!data.items[i]?.qty){
            return {
                success: false,
                msg: `items.${i}.qty is missing`
            }
        }
 
        if(typeof data.items[i].qty !== "number"){
            return {
                success: false,
                msg: `items.${i}.qty is needs to be number`
            }
        }
 
        if(!data.items[i]?.rate){
            return {
                success: false,
                msg: `items.${i}.rate is missing`
            }
        }
 
        if(isNaN(parseFloat(data.items[i].rate))){
            return {
                success: false,
                msg: `items.${i}.rate is not a valid number`
            }
        }
 
        if(!data.items[i]?.amount){
            return {
                success: false,
                msg: `items.${i}.amount is missing`
            }
        }
 
        if(isNaN(parseFloat(data.items[i].amount))){
            return {
                success: false,
                msg: `items.${i}.amount is not a valid number`
            }
        }
    }
 
    if(!data?.total){
        return {
            success: false,
            msg: `total is missing`
        }
    }
 
    if(isNaN(parseFloat(data?.total))){
        return {
            success: false,
            msg: `total is not a valid number`
        }
    }
 
    if(!data?.balanceDue){
        return {
            success: false,
            msg: `balanceDue is missing`
        }
    }
 
    if(isNaN(parseFloat(data?.balanceDue))){
        return {
            success: false,
            msg: `balanceDue is not a valid number`
        }
    }
 
    if(!data?.notes){
        return {
            success: false,
            msg: "notes is missing"
        }
    }
 
    if(!data?.terms){
        return {
            success: false,
            msg: "terms is missing"
        }
    }
 
    return {
        success: true
    }
}

 

 

And inside the above function we are checking for all the properties which needs to be present. Here we are using the if condition to validate the request data object. And if all the properties are present then we are returning the boolean property success to true.

 

 

And now we will be writing the getInvoice() method which is taking the request data object to convert the html to invoice pdf document. So you need to create a separate file called invoice.js file and copy paste the below code

 

 

invoice.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const HTMLToPDF = require('convert-html-to-pdf').default;
 
function getDeliveryItemsHTML(items){
    let data = ""
    for(let item of items){
        data += `
    <div class="table-row">
        <div class=" table-cell w-6/12 text-left font-bold py-1 px-4">${item.name}</div>
        <div class=" table-cell w-[10%] text-center">${item.qty}</div>
        <div class=" table-cell w-2/12 text-center">₹${item.rate}</div>
        <div class=" table-cell w-2/12 text-center">₹${item.amount}</div>
    </div>
    `
    }
    return data
}
 
function getDeliveryHTML(options){
    return `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Invoice</title>
    <style>
        /*! tailwindcss v3.0.12 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.flex{display:flex}.table{display:table}.table-cell{display:table-cell}.table-header-group{display:table-header-group}.table-row-group{display:table-row-group}.table-row{display:table-row}.hidden{display:none}.w-60{width:15rem}.w-40{width:10rem}.w-full{width:100%}.w-\[12rem\]{width:12rem}.w-9\/12{width:75%}.w-3\/12{width:25%}.w-6\/12{width:50%}.w-2\/12{width:16.666667%}.w-\[10\%\]{width:10%}.flex-1{flex:1 1 0%}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.justify-center{justify-content:center}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.border-x-\[1px\]{border-left-width:1px;border-right-width:1px}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.p-10{padding:2.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pl-4{padding-left:1rem}.pb-20{padding-bottom:5rem}.pb-16{padding-bottom:4rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pt-20{padding-top:5rem}.pr-10{padding-right:2.5rem}.pl-24{padding-left:6rem}.pb-6{padding-bottom:1.5rem}.pl-10{padding-left:2.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.font-normal{font-weight:400}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}
    </style>
</head>
<body>
    <div class="p-10">
        <!--Logo and Other info-->
        <div class="flex items-start justify-center">
            <div class="flex-1">
                <div class="w-60 pb-6">
                    <img class="w-40" src="${options.logo}" alt="Logo">
                </div>
                
                <div class="w-60 pl-4 pb-6">
                    <h3 class="font-bold">${options.name}</h3>
                    <p>${options.address1}</p>
                    <p>${options.address2}</p>
                </div>
                
                <div class="pl-4 pb-20">
                    <p class="text-gray-500">Bill To:</p>
                    <h3 class="font-bold">${options.customerName}</h3>
                </div>
                
            </div>
            <div class="flex items-end flex-col">
 
                <div class="pb-16">
                    <h1 class=" font-normal text-4xl pb-1">Delivery Report</h1>
                    <p class="text-right text-gray-500 text-xl"># ${options.orderId}</p>
                </div>
 
                <div class="flex">
                    <div class="flex flex-col items-end">
                        <p class="text-gray-500 py-1">Date:</p>
                        <p class="text-gray-500 py-1">Payment Terms:</p>
                        <p class="font-bold text-xl py-1 pb-2 ">Balance Due:</p>
                    </div>
                    <div class="flex flex-col items-end w-[12rem] text-right">
                        <p class="py-1">${options.date}</p>
                        <p class="py-1 pl-10">${options.paymentTerms}</p>
                        <div class="pb-2 py-1">
                            <p class="font-bold text-xl">₹${options.balanceDue}</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!--Items List-->
        <div class="table w-full">
            <div class=" table-header-group bg-gray-700 text-white ">
                <div class=" table-row ">
                    <div class=" table-cell w-6/12 text-left py-2 px-4 rounded-l-lg border-x-[1px]">Item</div>
                    <div class=" table-cell w-[10%] text-center border-x-[1px]">Quantity</div>
                    <div class=" table-cell w-2/12 text-center border-x-[1px]">Rate</div>
                    <div class=" table-cell w-2/12 text-center rounded-r-lg border-x-[1px]">Amount</div>
                </div>
            </div>
 
            <div class="table-row-group">
                ${getDeliveryItemsHTML(options.items)}
            </div>
        </div>
        
        <!--Total Amount-->
        <div class=" pt-20 pr-10 text-right">
            <p class="text-gray-400">Total: <span class="pl-24 text-black">₹${options.total}</span></p>
        </div>
 
        <!--Notes and Other info-->
        <div class="py-6">
            <p class="text-gray-400 pb-2">Notes:</p>
            <p>${options.notes}</p>
        </div>
 
        <div class="">
            <p class="text-gray-400 pb-2">Terms:</p>
            <p>${options.terms}</p>
        </div>
    </div>
</body>
</html>
    `
}
 
async function getInvoice(options) {
    return new Promise(async (resolve,reject) => {
        try {
            const html = getDeliveryHTML(options)
            const htmlToPDF = new HTMLToPDF(html)
 
            const pdf = await htmlToPDF.convert({waitForNetworkIdle: true, browserOptions: {defaultViewport: {width: 1920, height: 1080}}, pdfOptions: {height: 1200, width:900, timeout: 0}})
            resolve(pdf)
        } catch(err){
            reject(err)
        }
    })
}
 
module.exports = {
    getInvoice
}

 

 

As you can see we are importing the convert-html-to-pdf library and then we are using this library to convert the html template to pdf document. And then we are passing the html template to pdf document using the htmltopdf() constructor. And then we are using the convert() method to export html to pdf. And then we are exporting this method at the bottom.

 

 

And then we need to import this file at the top of the file in index.js file as shown below

 

 

Java
1
const {getInvoice} = require("./invoice");

 

 

Full Source Code

 

 

index.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
const express = require("express")
const {getInvoice} = require("./invoice");
const app = express()
app.use(express.json())
const PORT = 11000
 
const deliveryOptions = {
    logo: "https://thumbs.dreamstime.com/b/laundry-basket-icon-trendy-design-style-isolated-white-background-vector-simple-modern-flat-symbol-web-site-mobile-135748439.jpg",
    name: "Company Name",
    address1: "Some Road No 1",
    address2: "Some State, Pincode",
    orderId: "INV-001",
    customerName: "Sai Sandeep",
    date: "Oct 2, 2022",
    paymentTerms: "Delivery Items Receipt",
    items: [
        {
            name: "SINGLE BED_SHEET",
            qty: 3,
            rate: "10.00",
            amount: "30.00"
        },
        {
            name: "DOUBLE BED_SHEET",
            qty: 2,
            rate: "20.00",
            amount: "40.00"
        },
        {
            name: "TOWELS",
            qty: 3,
            rate: "5.00",
            amount: "15.00"
        },
        {
            name: "CLOTHES",
            qty: 3,
            rate: "50.00",
            amount: "150.00"
        }
    ],
    total: "235.00",
    balanceDue: "235.00",
    notes: "Thanks for being an awesome customer!",
    terms: "This invoice is auto generated at the time of delivery. If there is any issue, Contact provider"
}
 
function verifyBody(data){
    if(!data?.logo){
        return {
            success: false,
            msg: "logo is missing"
        }
    }
 
    if(!data?.name){
        return {
            success: false,
            msg: "name is missing"
        }
    }
 
    if(!data?.address1){
        return {
            success: false,
            msg: "address1 is missing"
        }
    }
 
    if(!data?.address2){
        return {
            success: false,
            msg: "address2 is missing"
        }
    }
 
    if(!data?.orderId){
        return {
            success: false,
            msg: "orderId is missing"
        }
    }
 
    if(!data?.customerName){
        return {
            success: false,
            msg: "customerName is missing"
        }
    }
 
    if(!data?.paymentTerms){
        return {
            success: false,
            msg: "paymentTerms is missing"
        }
    }
 
    if(!data?.date){
        return {
            success: false,
            msg: "date is missing"
        }
    }
 
    if(!data?.items){
        return {
            success: false,
            msg: "items is missing"
        }
    }
 
    for(let i = 0; i < data.items.length; i++){
        if(!data.items[i]?.name){
            return {
                success: false,
                msg: `items.${i}.name is missing`
            }
        }
 
        if(!data.items[i]?.qty){
            return {
                success: false,
                msg: `items.${i}.qty is missing`
            }
        }
 
        if(typeof data.items[i].qty !== "number"){
            return {
                success: false,
                msg: `items.${i}.qty is needs to be number`
            }
        }
 
        if(!data.items[i]?.rate){
            return {
                success: false,
                msg: `items.${i}.rate is missing`
            }
        }
 
        if(isNaN(parseFloat(data.items[i].rate))){
            return {
                success: false,
                msg: `items.${i}.rate is not a valid number`
            }
        }
 
        if(!data.items[i]?.amount){
            return {
                success: false,
                msg: `items.${i}.amount is missing`
            }
        }
 
        if(isNaN(parseFloat(data.items[i].amount))){
            return {
                success: false,
                msg: `items.${i}.amount is not a valid number`
            }
        }
    }
 
    if(!data?.total){
        return {
            success: false,
            msg: `total is missing`
        }
    }
 
    if(isNaN(parseFloat(data?.total))){
        return {
            success: false,
            msg: `total is not a valid number`
        }
    }
 
    if(!data?.balanceDue){
        return {
            success: false,
            msg: `balanceDue is missing`
        }
    }
 
    if(isNaN(parseFloat(data?.balanceDue))){
        return {
            success: false,
            msg: `balanceDue is not a valid number`
        }
    }
 
    if(!data?.notes){
        return {
            success: false,
            msg: "notes is missing"
        }
    }
 
    if(!data?.terms){
        return {
            success: false,
            msg: "terms is missing"
        }
    }
 
    return {
        success: true
    }
}
 
app.post("/getInvoice", (req,res) => {
    const result = verifyBody(req.body)
    if(result.success){
        getInvoice(req.body).then(pdf => {
            res.status(200)
            res.contentType("application/pdf");
            res.send(pdf);
        }).catch(err => {
            console.error(err)
            res.status(500).send({success: false, error: "something went wrong"})
        })
    } else {
        res.status(400).send(result)
    }
 
})
 
app.get("/sample", (req,res) => {
    res.status(200).send(deliveryOptions)
})
 
app.get("/", (req,res)=> {
    res.status(200).send({msg: "Hi there, welcome to Invoice API. Go to /sample route to get sample data"})
})
 
app.listen(PORT, () => {
    console.log(`Listening on PORT ${PORT}`)
})

Recent Posts

  • Angular 14/15 JWT Login & Registration Auth System in Node.js & Express Using MongoDB in Browser
  • Build a JWT Login & Registration Auth System in Node.js & Express Using MongoDB in Browser
  • React-Admin Example to Create CRUD REST API Using JSON-Server Library in Browser Using Javascript
  • Javascript Papaparse Example to Parse CSV Files and Export to JSON File and Download it as Attachment
  • Javascript Select2.js Example to Display Single & Multi-Select Dropdown & Fetch Remote Data Using Ajax in Dropdown
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme