Cordobo / angularx-qrcode

A fast and easy-to-use Angular QR Code Generator library with Ivy support

Home Page:https://cordobo.github.io/angularx-qrcode/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Plan for beeing supported by Server Side Rendering

M2Key opened this issue · comments

commented

Is there any plan for make it compatible with SSR.

Once I actived SSR, I received :
NodeInvocationException: Prerendering failed because of error: ReferenceError: document is not defined

Hello @M2Key,

from my perspective it looks like a cool feature, I will have a look into it.
Please feel free to provide sample code.

I have the same question,But my project use angular@4.0, I can't update to angular@5.0 . are you able to provide any methods to resolve it?

@cslgxuchang

Please provide some sample-code for me on a plunkr or jsfiddle.

@Cordobo use angularx-qrcode@1.0.2, my project use angular@4.0.0, when I run it with ssr, error "document is not defined" in angularx-qrcode@1.0.2 module . I have no idea to resolve it.

_20180326091934

These few changes makes SSR work for me:

angularx-qrcode.component.ts:

import {
	ChangeDetectionStrategy,
	Component,
	ElementRef,
	Input,
	OnChanges,
	OnInit,
	SimpleChange,
	AfterViewInit,
	Inject,
	PLATFORM_ID
} from '@angular/core';

declare var require: any;
var QRCode: any = undefined;

import { isPlatformServer } from '@angular/common';

@Component({
	selector: 'qrcode',
	changeDetection: ChangeDetectionStrategy.OnPush,
	template: ''
})

export class QRCodeComponent implements OnChanges, OnInit, AfterViewInit {

	/** @internal */
	@Input() public allowEmptyString: boolean = false;
	@Input() public colordark: string = '#000000';
	@Input() public colorlight: string = '#ffffff';
	@Input() public level: string = 'M';
	@Input() public hidetitle: boolean = false;
	@Input() public qrdata: string = '';
	@Input() public size: number = 256;
	@Input() public usesvg: boolean = false;

	public qrcode: any;

	constructor(
		public el: ElementRef,
		@Inject(PLATFORM_ID) private platformId: Object,
	) { }

	public ngOnInit() {
	}

	public ngAfterViewInit() {
		if (isPlatformServer(this.platformId)) {
			return;
		}
		else {
			if (!QRCode) {
				QRCode = require('qrcodejs2');
			}
			try {
				if (!this.isValidQrCodeText(this.qrdata)) {
					throw new Error('Empty QR Code data');
				}

				this.qrcode = new QRCode(this.el.nativeElement, {
					colorDark: this.colordark,
					colorLight: this.colorlight,
					correctLevel: QRCode.CorrectLevel[this.level.toString()],
					height: this.size,
					text: this.qrdata || ' ',
					useSVG: this.usesvg,
					width: this.size,
				});
			} catch (e) {
				console.error('Error generating QR Code: ' + e.message);
			}
		}
	}

	public ngOnChanges(changes: { [propertyName: string]: SimpleChange }) {
		if (!this.qrcode) {
			return;
		}

		const qrData = changes['qrdata'];

		if (qrData && this.isValidQrCodeText(qrData.currentValue)) {
			this.qrcode.clear();
			this.qrcode.makeCode(qrData.currentValue);
		}
	}

	protected isValidQrCodeText = (data: string): boolean => {
		if (this.allowEmptyString === false) {
			return !(typeof data === 'undefined' || data === '');
		}
		return !(typeof data === 'undefined');
	}

}

The main point is to not init QRCode when running server side, so I changed the import 'qrcodejs2' to a require being applied in ngAfterViewInit.

Since the code in ngOnInit now depends on ngAfterViewInit, I simply moved the code to that method, where we also know if QRCode is properly initialized.

Maybe a pull request and a new release on NPM?

Hi, I have installed two versions of this package (^1.2.4 and ^1.5.3) in differents proyects, but i´dont see if the code of @cbernth is all ready implemented, is that so in what version of the package can i see this code, please?

Hi @Dyabel03

No, the code from @cbernth has not been integrated into the repo yet.

Hi, @Cordobo thank you for your answer, currently I need this in my work so, do you have any plan to implement this anytime soon?... I really appreciate your effort in this project and I don´t wanna sound rude...thank you in advance.

P.S: Or if you know how I can implement this would also be helpful, I tried to use the code of @cbernth but when I execute the universal angular the same error occurs.

i need too for my work so, please could you help us to fix it for angular universal.
still same error when execute 😢

@Dyabel03 @alchemistt99 PRs are more than welcome!

commented

/frontend/dist/server.js:226874
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
^

ReferenceError: document is not defined

not working in 1.5.3

Thanks to code contributed by @cbernth and @ZhenhangTung, as of version 1.6.0, angularx-qrcode has fully implemented SSR support.

Closing this (please open another issue, if you encounter any)

I got

        var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
                     ^

ReferenceError: document is not defined

version 1.6.1 and version 1.6.0

Hi @naumov-dev, could you please provide a stripped down repo for me to reproduce?

@Cordobo Same thing happened to me. Here is my PR, but I don't know why my changes don't exist anymore on the dev branch, which has cost me several hours to find out the true problem. If you look at my company's fork, you will see the:

This branch is 4 commits ahead, 4 commits behind Cordobo:master.

On your master branch, my changes still don't exist.
Hope you could fix the problem soon. I'll just use the forked version for now.

@ZhenhangTung Thanks for your investigation, I have a look into it

@ZhenhangTung I have reapplied the PRs and released a fixed version 1.6.4. Thanks for your feedback!

Is it possible to generate the QR code from a component? I want to display a smaller version on the page, but when the user clicks the image generated from qrdata (wrapped in an anchor), I'd like to let them download a larger version. Can that be done?

@baywind2018 Could you show some pseudocode to us? From my understanding, the easiest way is to generate 2 QR code and make the larger one display: none. When a user clicks the image, which is the smaller one, we actually download the larger one.