Creating a dynamic image gallery in Handlebars using Express

I have successfully implemented handlebars with puppeteer to generate a PDF server-side and save it in my database. However, I am facing an issue with loading images stored in an assets directory through the img tag.

In my index.js file, I have a helper called img_picker which should return the path of the image based on the image name input. Below is my pdfGenerator function that takes a template.hbs file and utilizes puppeteer to generate the PDF:

    const puppeteer = require("puppeteer");
const hbs = require("handlebars");
const fs = require("fs-extra");
const path = require("path");

// Compiles the Handlebars docs
const compile = async (templateName, data) => {
  const filePath = path.join(
    process.cwd(),
    `${templateName}.hbs`
  );
  
  const html = await fs.readFile(filePath, "utf-8");
  return hbs.compile(html)(data);
};

hbs.registerHelper('img_picker', context => {
  console.log('IMAGE PATH: ', path.join(__dirname, 'server', 'reports', 'assets', `${context}@3x.png`))
  return path.join(__dirname, 'server', 'reports', 'assets', `${context}@3x.png`)
})

// Uses Puppeteer to take compiled HBS doc and create a PDF
const generatePDF = async (fileName, data) => {
  const browser = await puppeteer.launch({ args: ["--no-sandbox"], headless: true });
  const page = await browser.newPage();
  const content = await compile(fileName, data);
  await page.setContent(content);
  await page.emulateMedia("screen");
  const pdf = await page.pdf({
    format: "A4",
    printBackground: true
  });
  return pdf;
};

// Runs generator function generatePDF('template', {wedge: "Delivery"});

In my HBS file, I am attempting to use the image by referencing wedge.name as a string with the image name that is being iterated over in the data:

<!DOCTYPE html>
     <html>
          <head>
          </head>
               <body>
                    <img src="{{{img_picker wedge.name}}}" style="width: 70px;height:70px" />
               </body>
     </html>

I have seen examples using app.use(express.static()) for serving static files, but I'm unsure how to implement it in this scenario since the image path is dynamic based on the template.

package.json

"main": "index.js",
"dependencies": {
    "express": "^4.17.1",
    "fs-extra": "^8.1.0",
    "handlebars": "^4.7.3",
"puppeteer": "^2.1.1",

  }

Answer №1

Could you please offer a standalone example similar to this one?

const Mustache = require("mustache");
const fs = require("fs");

Mustache.parse('Hello, {{name}}!');
const output = Mustache.render('Hello, {{name}}!', { name: "World" });
console.log(output);
{
  "title": "Sample Project",
  "description": "A simple project setup",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "John Doe",
  "license": "MIT",
  "dependencies": {
    "mustache": "^4.2.0"
  }
}
$ node index.js
Hello, World!

Answer №2

Looking to understand the differences between page.goto and page.setContent? Consider utilizing page.goto for loading remote content or using page.setContent with images encoded in base64 format. For further clarification, check out this article.

await  page.goto(`data: text/html ,${content}`, {waitUntil:'networkidle0'});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Choosing an option in react-select causes the page to unexpectedly shift

Encountering a problem with a mobile modal developed using react-select. The selectors are within a div with fixed height and overflow-y: scroll. Upon selecting an option for the 'Choose observer' select, the entire modal briefly jumps down in th ...

Empty req.body object in Node.js

I came across this code snippet: const bodyParser = require("body-parser"); const express = require("express"); const app = express(); app.use(express.json()); app.use(bodyParser.json()); app.post("/api/foo", (request, response) => { let foo = { ...

At what point does Math.random() begin to cycle through its values?

After running this simple test in nodejs overnight, I found that Math.random() did not repeat. While I understand that the values will eventually repeat at some point, is there a predictable timeframe for when it's likely to happen? let v = {}; for ( ...

The <iframe> generated by Create-React-App often hinders my ability to interact with or modify the application directly, requiring me to remove it using the browser's element editor

After conducting a global installation of create-react-app, I encountered an issue where instead of editing the rendered content directly in the browser while working on a project, there is a mysterious container created around my app. Upon closer examina ...

Leveraging global variables within Vuex state management strategy

I have successfully added custom global variables into Vue by injecting them. Here is the code snippet: export default function (props, inject) { inject('models', { register(name) { const model = require(`@/models/${name}. ...

What is the best way to pass a cookie across multiple subdomains?

I am currently facing an issue with my setup where my express backend is hosted on , and the front-end is hosted on . The problem arises after logging in the frontend, as the auth server sets a cookie with "example.com" as the domain attribute, but the bro ...

Scraping dynamic content with Python for websites using JavaScript-generated elements

Seeking assistance in using Python3 to fetch the Bibtex citation produced by . The URLs follow a predictable pattern, enabling the script to determine the URL without requiring interaction with the webpage. Attempts have been made using Selenium, bs4, amon ...

Remove any elements using jQuery that do not contain any content

I need to remove any empty elements from my HTML code. Here is an example of the HTML markup: The HTML markup is stored in a jQuery variable called 'myhtml' and it may contain various tags. <h1> <u> <strong></st ...

Automatically injecting dependencies in Aurelia using Typescript

Recently, I started working with Typescript and Aurelia framework. Currently, I am facing an issue while trying to implement the @autoinject decorator in a VS2015 ASP.NET MVC 6 project. Below is the code snippet I am using: import {autoinject} from "aure ...

Updating the status or condition of an item in express and react by using its field value

Currently, I have a table in my database named Item which includes a condition/status field and an expiry_date field. My backend is built using expressjs+prisma while the frontend uses react. Here's a snippet of what the table structure looks like: mo ...

Obtain the inner text input value using jQuery

In my form, there is a feature that adds a new row of text inputs dynamically when a user wants to add more rows. Each new row is automatically populated with input fields that have the same id and class as the previous ones. My question is: how can I re ...

Is it possible to implement two distinct passport local strategies within a single application? And if so, what is the process for doing so

Recently, I've been working on an application with two different levels of authentication. The first level involves a group account where multiple individuals share a single login using group credentials (a group username and password). Once logged ...

Adding ngChange programmatically in Angular without using attributes is a common challenge faced

I am attempting to replicate the functionality of the ng-change attribute within a directive without making changes to the HTML (thus excluding the use of the ng-change property). After examining the Angular source code for the ngChange directive, I have ...

"Performing a series of getJSON requests with a delay between each call, iterating through an array

Could someone shed light on why my jQuery/JavaScript code runs with an unexpected flurry of ajax calls instead of at a steady 1-per-second rhythm? var i = 0, l = data.length; function geocode() { $.getJSON( 'https://maps.googleapis.com/maps/api ...

Next.js, Knex, and SWR: Unusual issue disrupting queries

When making API requests using Next API routes and interacting with Knex + MySQL, along with utilizing React and SWR for data fetching, I encountered a strange issue. If a request fails, my SQL queries start to append ", *" to the "select" statement, causi ...

Determine the presence of a JSON Value/Array in a web application using JavaScript and visualize the information in a dynamic

Utilizing the Ticketmaster API has provided me with a sample dataset from their platform, Data 1 - Including information on "presales." "sales": { "public": { "startDateTime": "2019-11 ...

Express fails to pass password validation

I encountered an issue with a ValidationError stating that the Path password is required while attempting to register a new User. My experience in Node, programming, and authentication is limited. Below is the code for the User model and schema where I ma ...

Vue for Number Crunching

Learning vueJS is quite new to me. I am attempting to capture two input values, add them together, and display the result. I have encountered a strange issue where when subtracting number1 from number3, multiplying number1 with number2, or dividing number ...

Stop the Text Table from being highlighted

My webpage includes a dynamic table where users can select multiple rows. jQuery events and CSS are utilized to provide visual feedback when a row is selected. However, pressing the shift key sometimes causes text to become highlighted, which is not idea ...

The Colorful World of CSS Backgrounds

I've been searching for hours trying to track down the source of this strange greenish background color. I've combed through every single file and it's starting to drive me insane. Any ideas where this color could be coming from? I highly d ...