Can't display base64 QR code in Template

I'm using node-red-contrib-qrcode-generator to create a Wi-Fi QR code, and then wish to display it in Template node. But can't get it to display.

The msg.payload input to the Template is correct:
14/09/2021, 20:59:01node: faa07eea3182dc1dmsg : Object
object
_msgid: "deb55908c44eaed7"
payload: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAACUCAYAAAB1PADUAAAAAklEQVR4AewaftIAAATRSURBVO3BQY4jRxAEwfAC//9l1xzzVE ...truncated for post..."

I have tried formats like below but all I get displayed is missing image icon:
(also tried enclosed in " ")
(also tried enclosed in " ")
<img src="{{msg.payload}}">

If I copy msg.payload from debug and do this it displays fine:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJ ...truncated for post..."

Try triple curly braces

<img src="{{{msg.payload}}}">

Thx - given that a try and with triple braces and it doesn't show anything at all on the page, not even missing image icon. In Chrome dev it just shows this for the response <img src="" />

Sorry, in original post hadn't preformatetd the text so had tried: <img src={{msg.payload}} /> and also in quotes.

I noticed from another old post someone seems to have got a base64 QR code to display using the format below. Seems a bit strange to have the image header info first as it should be inlcued in the file like it is in my payload (?). Anyway, tried it with double and triple curly braces and get a missing image icon for both.

<img src="data:image/png;base64,{{msg.payload}}" />

This works for me...

image

Uses node-red-contrib-image-tools

Demo flow...

[{"id":"5bb019b65d5f0af7","type":"inject","z":"af952aeaa20f4f97","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1330,"y":680,"wires":[["f62c2ee556bf4e86"]]},{"id":"f62c2ee556bf4e86","type":"Barcode Generator","z":"af952aeaa20f4f97","name":"","data":"www.google.com","dataType":"str","barcode":"qrcode","barcodeType":"barcode","options":"","optionsType":"ui","sendProperty":"payload","props":[{"p":"rotate","v":"N","vt":"str"},{"p":"includetext","v":"true","vt":"bool"},{"p":"textxalign","v":"center","vt":"str"}],"x":1480,"y":680,"wires":[["72583360f1fa1443"]]},{"id":"72583360f1fa1443","type":"jimp-image","z":"af952aeaa20f4f97","name":"","data":"payload","dataType":"msg","ret":"b64","parameter1":"","parameter1Type":"msg","parameter2":"","parameter2Type":"msg","parameter3":"","parameter3Type":"msg","parameter4":"","parameter4Type":"msg","parameter5":"","parameter5Type":"msg","parameter6":"","parameter6Type":"msg","parameter7":"","parameter7Type":"msg","parameter8":"","parameter8Type":"msg","sendProperty":"payload","sendPropertyType":"msg","parameterCount":0,"jimpFunction":"none","selectedJimpFunction":{"name":"none","fn":"none","description":"Just loads the image.","parameters":[]},"x":1630,"y":680,"wires":[["0f10978fe0469748"]]},{"id":"0f10978fe0469748","type":"image viewer","z":"af952aeaa20f4f97","name":"","width":160,"data":"payload","dataType":"msg","active":true,"x":1790,"y":680,"wires":[["eb155874df4dc7f4"]]},{"id":"eb155874df4dc7f4","type":"ui_template","z":"af952aeaa20f4f97","group":"a348b0ef9d248038","name":"","order":3,"width":"6","height":"5","format":"<img src=\"{{msg.payload}}\" style=\"height: 100%;\" />","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1960,"y":680,"wires":[[]]},{"id":"a348b0ef9d248038","type":"ui_group","name":"Default","tab":"3316deba5234ba30","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"3316deba5234ba30","type":"ui_tab","name":"test","icon":"dashboard","disabled":false,"hidden":false}]

Weird or whatever, but using just "payload" works:

`<img src="{{payload}}"/>

This is the abbreviated debug output of my Template using above format which shows the msg payload being inserted in the returned page:
<img src="data:image&#x2F;png;base64,iVBORw0KGgoAAAANSUhEU...

When I use:

<img src="{{msg.payload}}"/>

it doesn't display and the Template debug output shows no content:
<img src=""/>

Would be interested to undertand why it doesn't require msg prefix in my case...

in that case you need to provide

  • a simple version of your flow that shows the issue.
  • what device are you running NR on?
  • what OS are you using?
  • what release of NR and node.js? (you can get this from the startup log)

That way someone can try to reproduce it.

Simple flow is below.

Requires node-red-contrib-qrcode-generator v0.4.0, other than that I think its all standard NR UI nodes (NR v2.0.5, node-red-dashboard v2.30.0). Host is Ubuntu 20.04.2. Node.js is v14.17.5.

As it is when I go to http://ip:1880/createqr it displays the QR code after creation. If I change "payload" in the template to be "msg.payload" then it no longer displays.

[{"id":"5cd74878ed83ecb5","type":"tab","label":"Test","disabled":false,"info":""},{"id":"d6d6f7b56064f74e","type":"http in","z":"5cd74878ed83ecb5","name":"","url":"/CreateQR","method":"get","upload":false,"swaggerDoc":"","x":160,"y":120,"wires":[["cba6749e8bc6d9ad"]]},{"id":"cba6749e8bc6d9ad","type":"function","z":"5cd74878ed83ecb5","name":"Set QR ","func":"var newMsg = {};\nnewMsg.req = msg.req;\nnewMsg.res = msg.res;\n\n//Setup QR code with the Tenant Wi-Fi SSID and users DPSK\nnewMsg.qrcodeinput = \"WIFI:T:WPA;S:Tenant WiFi;P:12345abcde;\";\n\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":120,"wires":[["cd7be2c8e9f955c0"]]},{"id":"cd7be2c8e9f955c0","type":"qrcode-generator","z":"5cd74878ed83ecb5","name":"","qrtype":"wifi2qr","text2qrText":"","ssid":"","hiddenssid":false,"wifitype":"WPA","phonenum":"","smsphonenum":"","smstext":"","mailto":"","mailsubject":"","mailbody":"","latitude":"","longitude":"","colorlight":"#ffffff","colordark":"#000000","printstatus":false,"x":670,"y":120,"wires":[["30f473f439fbd7cc","6e9ed917870511a2"]]},{"id":"30f473f439fbd7cc","type":"template","z":"5cd74878ed83ecb5","name":"Display QR code","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>QR code</title>\n<style>\nh1 {font-family: \"Arial\";font-size: 23px;font-weight: bold;}\nh2 {font-family: \"Arial\";font-size: 18px;font-weight: normal;}\n</style>\n</head>\n<body>\n    <h2>You can scan the QR code to automatically connect Android v9+ and iOS v11+ devices using your Wi-Fi Access Key.</h2>\n    <h2>It will also be emailed to you with the service confirmation and you can forward/print it out.</h2>\n    <img src=\"{{payload}}\"/>\n</body>\n</html>","output":"str","x":930,"y":120,"wires":[["9829dac5f9937e9f"]]},{"id":"9829dac5f9937e9f","type":"http response","z":"5cd74878ed83ecb5","name":"","statusCode":"200","headers":{"Connection-Timeout":"\"Connection-Timeout\" \":\" 240"},"x":1140,"y":120,"wires":[]},{"id":"6e9ed917870511a2","type":"debug","z":"5cd74878ed83ecb5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":910,"y":180,"wires":[]}]

would be best not to use contrib nodes in your example if not really required . You could copy the base64 data uri and add it to a inject node, then others would not need to install anything unneeded

Ok, thats a fair coment, but the contrib node is the one I'm using to ceate the QR code in the first place. Guess I could do that using javascript in function node, or browser, but this is easisest way. And the format of the payload it creates is correct, its just the template doesn't accept it as msg.payload.

Use your flow to generate a QR code and feed it into a debug node. Then use the little Copy button that appears when you hover over it in the debug pane, to copy it. Then paste that into an Inject node configured for JSON. The result will be an inject node that generates the QR code for testing the rest of the flow.

Is this another way of doing what you mean?

  1. I had the http get connected to Set QR node (as per red dotted line) to create the QR code.
  2. Copied the debug (QR code) data into the function node as newMsg.payload.
  3. Moved the http get connection to the function node and refreshed the web page.

When I have the template img src set to {{payload}} it dislays the QR code fine; when I have it set to {{msg.payload}} it doesn't.

So exact same behaviour as when I take the output of qrcode-gen directly into Display QR code template node...

The generated QR code is valid - I can paste the debug data straight into browser and it displays the QR code.

So something odd why the template node is requiring just "payload" instead of "msg.payload".

Function node setting the newMsg payload as the generated QR code data out of debug:

var newMsg = {};
newMsg.req = msg.req;
newMsg.res = msg.res;

newMsg.payload = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAACUCAYAAAB1PADUAAAAAklEQVR4AewaftIAAAS/SURBVO3BQY4bSRAEwfAC//9l3znmqYBGJ2clIczwR6qWnFQtOqladFK16KRq0UnVopOqRSdVi06qFp1ULTqpWnRSteikatFJ1aKTqkUnVYs+eQnIb1IzAZnUbAIyqflNQH6TmjdOqhadVC06qVr0yTI1m4D8SYDcqLkBcqPmRs0mIJtOqhadVC06qVr0yZcBeULNE2omIJOaCcgTaiYgN0Bu1ExA3gDyhJpvOqladFK16KRq0Sd/OSA3QCY1fxI1/5KTqkUnVYtOqhZ98pdTMwG5AfKGmgnIE0AmNf+Sk6pFJ1WLTqoWffJlav5kam6APKFmAvJNav4kJ1WLTqoWnVQt+mQZkN8EZFIzAZnUTEAmNd+kZgIyqbkB8ic7qVp0UrXopGoR/shfDMiNmieAfJOaf9lJ1aKTqkUnVYs+eQnIpGYCcqNmAvKEmgnIDZBJzRNqJiCTmhsgN2omIJOaGyCTmgnIjZo3TqoWnVQtOqla9MmXqbkBcqNmAnKj5kbNBGRScwPkCSCTmhsgk5oJyBtqJiCbTqoWnVQtOqlahD/yApAbNU8AuVHzBpBJzQ2QSc0bQJ5QswnIjZo3TqoWnVQtOqla9MlLam6ATGomIJOaGyA3aiYgTwC5ATKpmYDcqJmATGpugExq3lCz6aRq0UnVopOqRZ98mZo3gExqJiATkBs1N2pugExAfpOaGyBPAJnUvHFSteikatFJ1aJPlgG5UTOpuVEzAZnUTEDeADKpuVEzAZnUTEAmNROQSc0E5Ak1N0A2nVQtOqladFK1CH/kfwRkUjMBuVHzBJBJzQ2QSc0E5EbNBORPpuaNk6pFJ1WLTqoW4Y8sAnKj5g0gk5pNQCY1N0AmNU8AeULNBOQJNd90UrXopGrRSdWiT75MzQ2QJ9RMQG7U3ACZ1DyhZgIyqflNam6ATGo2nVQtOqladFK16JNlam6APKHmNwGZ1ExAbtRMQG7UvKHmCTXfdFK16KRq0UnVok9eAjKpmYDcqLkBMql5A8iNmifUTEBu1LwB5EbNDZBJzaaTqkUnVYtOqhZ98pKaJ9RMQCY1k5on1ExAJjUTkDeAPAHkRs0EZFJzA+QJIJOaN06qFp1ULTqpWoQ/sgjIpOYJIDdqJiCTmieA3Kh5AsikZgLyf1LzTSdVi06qFp1ULcIf+YsBuVEzAdmk5gbIpGYCMql5AsgTar7ppGrRSdWik6pFn7wE5DepuVEzAXlDzRtq3gAyqXlCzQRkUrPppGrRSdWik6pFnyxTswnIE0AmNROQSc0TQCY1N0AmNU+oeULNE0AmNW+cVC06qVp0UrXoky8D8oSaJ9TcALkBMqmZgNwA2QTkm9R800nVopOqRSdViz75ywGZ1NyoeUPNBOQJIJOaN4DcAJnUfNNJ1aKTqkUnVYs++cepmYDcqHlCzQRkUvMEkBs1T6i5ATKpeeOkatFJ1aKTqkWffJmab1LzhpoJyBtqngAyqbkBMqmZgPyfTqoWnVQtOqla9MkyIL8JyI2aJ9RMQJ4A8oSaGyBPqJmATGq+6aRq0UnVopOqRfgjVUtOqhadVC06qVp0UrXopGrRSdWik6pFJ1WLTqoWnVQtOqladFK16KRq0UnVopOqRf8BPVkxI7xwLnQAAAAASUVORK5CYII=";

return newMsg;

You are using the standard template node which uses {{payload}}, in you original image you are using the ui-template node that uses{{msg.payload}}. Best to use {{{ }}} as the base64 string will be url encoded if only {{ }}. I would help more but i have the cntrib nodes install and no data to work with.

I've been using the standard template node throughout. It was Steve-Mcl post that shows the ui-template node.

So if you say {{payload}} is the expected format in standard template then its working correctly, I just missed that in the documentation and searches. Thx for clarifying.

I gues the help doc could be made more specific on this point. It does hint at this in the example "Hello {{payload.name}}. Today is {{date}}" where you can see no "msg." prefix mentioned, but thats pretty subliminal :wink: